我正在创建一个程序,用户只需要服务器知道的用户名和密码登录服务器。他们有4次尝试获取正确的用户名和密码。如果他们在4次尝试中未输入正确的登录信息,则服务器将关闭与客户端的连接。
我需要帮助的程序的下一部分是永久禁止用户连接以进行进一步的尝试。当用户第一次登录并且错误地完成所有4次尝试时,他们的IP地址被写入名为“userIP.txt”的文件。
我尝试做的是读取文件,如果它与用户的IP地址匹配,它们将被禁止进入该程序。它不起作用 - 当他们回到程序时,它会让他们再次登录。
我有什么想法可以解决这个问题吗?
以下是服务器代码的一部分:
import java.lang.*;
import java.io.*;
import java.net.*;
class Server {
public static void main(String args[]) throws FileNotFoundException {
String welcome = "Welcome! The server is now connected.";
String login = "Enter username and password: ";
String message;
PrintWriter writer = new PrintWriter("userIP.txt");
try {
//Detecting the localhost's ip address
InetAddress localaddr = InetAddress.getLocalHost();
System.out.println("SERVER\n");
System.out.println ("Local hostnameIP: " + localaddr );
// Creating a server socket for connection
ServerSocket srvr = new ServerSocket(1234);
System.out.println("Waiting for connection on "+localaddr);
// Accept incoming connection
Socket skt = srvr.accept();
System.out.print("Server has connected!\n");
// get Input and Output streams
PrintWriter out = new PrintWriter(skt.getOutputStream(), true);
out.flush();
BufferedReader in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
BufferedReader log = new BufferedReader(new InputStreamReader(skt.getInputStream())); //read input for login
System.out.print("Sending string: '" + welcome + "'\n");
out.println(welcome);
String ip = localaddr.getHostAddress();
//read file
String checkIP = "userIP.txt";
String line = null;
try {
FileReader readFile = new FileReader (checkIP);
BufferedReader br = new BufferedReader (readFile);
while ((line = br.readLine())!= null) {
System.out.println("reading file: " + line);
if (line==ip) {
System.out.println("IP MATCHES");
//closing server
out.println("You are banned. Server closing.");
out.close();
skt.close();
srvr.close();
}
}
br.close();
}
catch (FileNotFoundException ex) {
System.out.println("Unable to open file '" + checkIP + "'");
}
catch(IOException ex) {
System.out.println("Error reading file '" + checkIP + "'");
}
//login attempts
int tries = 4;
while (tries>0) {
out.println(login);
//login
String username = in.readLine();
System.out.println("Client's username: " + username);
String password = in.readLine();
System.out.println("Client's password: " + password);
if (username.equals("hello123") && password.equals("mypass")) {
out.println("Correct login!");
System.out.println ("Client's IP Address: " + localaddr.getHostAddress());
tries=-1;
}
else { //if wrong login - give 3 more tries
tries--;
System.out.println("Number of tries left: " + tries);
out.println("Try again. Login attempts left - " + tries);
}
}
if (tries==0){
out.println("Wrong login - server closing");
out.close();
skt.close();
srvr.close();
//ban ip address permanently
System.out.println(localaddr.getHostAddress());
writer.println(localaddr.getHostAddress()); //write ip address to file
writer.close();
}
如果您需要客户端代码,请告诉我。感谢所有帮助!
答案 0 :(得分:3)
首先,按引用比较字符串而不是值更改
if (line==ip)
到
if ( line.equals(ip) )
更新:无需使用replaceAll();正如@EJP在评论中提到的那样。
readLine()删除行终止符。 replaceAll()调用是 因此没必要。
此外,您使用PrintWriter
将以覆盖模式打开文件,在检查禁止列表之前文件将为空。请改用FileWriter
。
PrintWriter writer = new PrintWriter(new FileWriter("userIP.txt", true));
你得到了错误的InetAddress地址。您需要获取客户端地址,然后将其更改为
Socket skt = srvr.accept();
InetAddress clientInetAddress = skt.getInetAddress();
ip = clientInetAddress.getHostAddress();
但IP阻止是错误的。在现实世界的示例中,多个用户共享相同的IP地址,即NAT公共IP地址。最好在特定时间内阻止特定用户的登录尝试。所以你阻止用户30分钟然后增加持续时间然后永久阻止用户并要求第二种验证方法,如电话或电子邮件。