【问题标题】:Java networking - how to permanently ban ip address?Java 网络 - 如何永久禁止 IP 地址?
【发布时间】:2018-09-04 19:15:20
【问题描述】:

我正在制作一个程序,用户使用只有服务器知道的用户名和密码登录服务器。他们有 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();

        }

如果您需要客户端代码,请告诉我。感谢所有帮助!

【问题讨论】:

标签: java networking login server ip-address


【解决方案1】:

首先你通过引用而不是值变化来比较字符串

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 分钟,然后增加持续时间,然后永久屏蔽用户并要求使用第二种验证方法,例如电话或电子邮件。

【讨论】:

  • "但是通过 IP 屏蔽是错误的。" 完全正确。
  • 啊,是的!我完全忘记了.equals。感谢您让我知道客户端的ip不同,我只是在学习网络。但是,如果客户回到该计划,他们不会被永久禁止 - 知道如何解决这个问题吗?
  • 是同网的客户端,编辑代码后客户端ip是多少?
  • 我仔细阅读了您的代码。在检查禁止列表之前,您使用 PrintWriter 打开覆盖文件内容的文件,而不是使用 FileWriter。 PrintWriter writer = new PrintWriter(new FileWriter("userIP.txt", true));
  • readLine() 删除行终止符。因此,replaceAll() 调用是不必要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-03
  • 2021-05-31
  • 1970-01-01
  • 1970-01-01
  • 2021-10-25
  • 1970-01-01
相关资源
最近更新 更多