0

我正在使用 TCP Sockets 编写一个简单的客户端-服务器应用程序。它采用多线程原理,允许多个客户端连接到同一服务器。

我在弄清楚我使用套接字时遇到的一些错误时遇到了一些麻烦,正如您可能会说的那样,我在这个环境中相当新。

我将向您展示我拥有的代码以及从中获得的输出,但基本上问题在于客户端与服务器的连接,我运行了所有代码但仍然找不到问题所在它。

服务器:

public static ArrayList<String> userList = new ArrayList<String>();
public static int index;
public static String date;
public static void main(String args[]) throws Exception {//inicio main      


    ServerSocket server = new ServerSocket(6500);   //Create socket on port 6500
    System.out.println ("Server started on port 6500");     
    while (true){   //Waiting for clients
        System.out.println("Server waiting for client connections..");
        Socket socket = null;
        BufferedReader reader = new BufferedReader(new FileReader("C:\\UNIV\\Redes\\workspace\\Copy of Ex_4.3_Teste\\lists\\blacklist.txt"));
        String line = null;
        socket = server.accept();

        // Blacklist verification
        while ((line = reader.readLine()) != null) {
            if (line.equals(socket.getInetAddress().toString())) {
                System.out.println("IP Blacklisted: " + socket.getInetAddress().toString());
                System.out.println("Closing connection to " + socket.getInetAddress().toString());
                PrintStream checkBlack = new PrintStream(socket.getOutputStream(),true);
                checkBlack.println("***BLACKLISTED***");
                reader.close();
                checkBlack.close();
                socket.close();
                break; 
            }
        }//End of Blacklist Verification

        //Sending feedback in case of approved client
        try { 
        PrintStream checkBlack = new PrintStream(socket.getOutputStream(),true);
        checkBlack.println("***NBLACKLISTED***");
        checkBlack.close();
        } catch (SocketException e) {

        }
        userList.add(socket.getInetAddress().toString()); //Add connected user's IP to USERLIST
        System.out.println("New connection..");
        System.out.println("Size of UserList: " + userList.size());
        Thread t = new Thread(new EchoClientThread(socket)); 

        t.start(); //Starting Client Thread


    }//End of Waiting for Clients       
}//End of Main  

public static class EchoClientThread implements Runnable{
    private Socket s;
    public EchoClientThread(Socket socket) {
        this.s = socket;
    }
    public void run() { 
        String threadName = Thread.currentThread().getName();   //Thread Name
        String stringClient = s.getInetAddress().toString();    //Client IP
        System.out.println("Connected to " + stringClient); 

        try{                
            BufferedReader input = new BufferedReader(
                    new InputStreamReader(s.getInputStream()));         
            PrintStream output = new PrintStream(
                    s.getOutputStream(),true);
            String line;
            while ((line = input.readLine()) !=null) {  //Input Cycle   

                System.out.println (stringClient+": "+threadName+": "+line);    //Print command from client

                if (line.equalsIgnoreCase("9")){ //Exit
                    break;
                }

                else if (line.equalsIgnoreCase("1")){   //Send List of Online Users
                    System.out.println("Option 1: Sending list of online users to " + stringClient);
                    output.println(" ");
                    output.println("List of Online Users:");
                    output.println(" ");
                    for(int i=0;i<userList.size();i++){
                        output.println(userList.get(i));
                    }
                }

                else if (line.equalsIgnoreCase("2")) {  //Send message to a single user
                    System.out.println("Nothing here yet..");
                }

                else if (line.equalsIgnoreCase("3")) {  //Send message to all the online users
                    System.out.println("Nothing here yet..");
                }

                else if (line.equalsIgnoreCase("4")){   //Send User Blacklist
                    System.out.println("Option 4: Sending user blacklist to " + stringClient);
                    BufferedReader reader = new BufferedReader(new FileReader("C:\\UNIV\\Redes\\workspace\\Copy of Ex_4.3_Teste\\lists\\blacklist.txt"));
                    String lineRead = null;
                    output.println(" ");
                    output.println("User Blacklist:");
                    output.println(" ");
                    while ((lineRead = reader.readLine()) != null) {
                        output.println(lineRead);
                    }
                    reader.close();
                }

                else{
                    output.println("Unknown command.");
                }   

                output.println("***CLOSE***");  //Closes client's input cycle
                output.println("***NBLACKLISTED***");   //Sending feedback in case of approved client                       
            }//Input Cycle End

            output.println("See you later!"); 
            input.close();  //Closes inputStream 
            output.close(); //Closes outputStream
            s.close();  //Closes Socket                         
        }
        catch (Exception e){
            System.err.println("Server Side Error!");
            System.out.println(e);
        }
        userList.remove(s.getInetAddress().toString());
        System.out.println("Client "+ stringClient+" was disconnected!");                   
    }//End of run()  
}//End of EchoClientThread
}//End of EchoServerThread

客户:

public static void main(String args[]) throws Exception {
    if (args.length !=1){
        System.err.println ("usage: java EchoClient2 <host>");
        System.exit(1);
    }               
    String host = args[0];
    int port = 6500;
    String cmd, line;
    Socket socket = new Socket(host,port);
    BufferedReader input = new BufferedReader(
            new InputStreamReader(socket.getInputStream()));
    PrintStream output = new PrintStream(socket.getOutputStream(),true);

        while( true ) {//Input cycle 

            Scanner scan = new Scanner (System.in);
            if (input.readLine().equals("***BLACKLISTED***")) {
                System.out.println("IP is Blacklisted");
                break;
            }
            System.out.println(" ");
            System.out.println("CLIENT MENU");
            System.out.println(" ");
            System.out.println("1 - List on-line users");
            System.out.println("2 - Send message to a single user");
            System.out.println("3 - Send message to all on-line users");
            System.out.println("4 - List Blacklisted Users");
            System.out.println("9 - Exit");
            System.out.println(" ");
            System.out.print(host+":"+port+"#>");   //Command prompt            
            cmd = scan.nextLine();  //Scanning command to send to the server    
            output.println(cmd);    //Sending command to the server

            if ( cmd.equalsIgnoreCase("9")){
                System.out.println("Exiting..");
                break;
            } 

            try {
            while (!(line = input.readLine()).equals("***CLOSE***")) {  //Input Cycle                           
            System.out.println (line);  //Prints server answer      
            }
            } catch (Exception e) {
                System.err.println("Client Side Error!");
                System.out.println(e);
                break;
            }

        }//End of Cycle

    System.out.println("Connection Terminated");
    input.close();  //Closes inputStream
    output.close(); //Closes outputStream
    socket.close(); //Closes Socket 
}
}

因此,服务器以以下输出正常启动:

Server started on port 6500
Server waiting for client connections..

但是一旦我尝试与客户端连接,就会发生这种情况:

服务器端:

Server started on port 6500
Server waiting for client connections..
New connection..
Size of UserList: 1
Server waiting for client connections..
Connected to /127.0.0.1
java.net.SocketException: Socket is closed
Server Side Error!
Client /127.0.0.1 was disconnected!

但是,在客户端,它仍然显示输入菜单和命令提示符,如下所示:

CLIENT MENU

1 - List on-line users
2 - Send message to a single user
3 - Send message to all on-line users
4 - List Blacklisted Users
9 - Exit

127.0.0.1:6500#>

当我在客户端提示符上输入内容时,我得到:

127.0.0.1:6500#>1
Client Side Error!
java.net.SocketException: Software caused connection abort: recv failed
Connection Terminated

我知道错误的含义,Socket is closed这几乎是不言自明的,但我只是找不到导致套接字关闭的代码问题。

任何帮助深表感谢。

4

1 回答 1

2

您的黑名单机制不太正确。

当您关闭与套接字关联的流时,它也会关闭套接字。

因此,服务器正在关闭它获得的任何套接字,然后将其交给一个线程,该线程试图使用该套接字并失败。

    // Blacklist verification
    while ((line = reader.readLine()) != null) {
        // blah blah blah
    }//End of Blacklist Verification

    //Sending feedback in case of approved client
    try { 
        PrintStream checkBlack = new PrintStream(socket.getOutputStream(),true);
        checkBlack.println("***NBLACKLISTED***");
        checkBlack.close();  // <== why are you closing the stream?
    } catch (SocketException e) {

    }

试试这个

    // Blacklist verification
    while ((line = reader.readLine()) != null) {
        // blah blah blah
    }//End of Blacklist Verification

    //Sending feedback in case of approved client
    try { 
        socket.getOutputStream().write("***NBLACKLISTED***\n".getBytes());
    } catch (SocketException e) {
        e.printStackTrace();
    }

调试器是你的朋友。

于 2013-06-17T00:06:36.640 回答