使用线程的Java网络,当一个客户端离开另一个客户端时无法与服务器通信

时间:2012-03-21 15:07:02

标签: java multithreading

我正在尝试在java中创建一个接受客户端的服务器。目前,两个客户端可以连接到服务器。但是,当一个人离开时,另一个客户端无法再与服务器通信。我认为问题是我的clientSocket是在我的线程之外创建的,这意味着它必须被声明为'final',因为我使用了一个内部类。但是,如果我将它移动到线程中,则无法创建clientSocket。有想法该怎么解决这个吗?提前致谢。

注释:如果我在客户端离开时关闭clientSocket,则显示“Broken Pipe”错误,因为clientSocket是最终的,因此无法更改 - 即clientSocket对于两个客户端都是相同的。

private BufferedWriter writer;  
private LODGame game; 
public Server(int port) throws Exception {
    try{
        // Listen on the given port.
        serverSocket = new ServerSocket(port);
    game = new LODGame();
    }
    catch(BindException e){
        throw new Exception("Failed to create a server socket: "+
                    e.getMessage());
    }
}
public Server(int port, String map) throws Exception {
    try{
        // Listen on the given port.
        serverSocket = new ServerSocket(port);
    game = new LODGame(map);
    }
    catch(BindException e){
        throw new Exception("Failed to create a server socket: "+
                    e.getMessage());
    }
}


public void run() throws Exception {

    final ServerSocket serverSocket = getServerSocket();

while (true){
    System.out.println("Listening for a client on port: "+
               serverSocket.getLocalPort());
    // Wait for a client to make contact.
    final Socket clientSocket = serverSocket.accept(); 
    // Contact ...
    System.out.println("A client has arrived.");

    Thread serverThread = new Thread(){
        public void run(){
        boolean quit = false;
        while (!quit){
            try{
            // Wrap the input stream in a BufferedReader.
            BufferedReader reader = new BufferedReader(
                                   new InputStreamReader(clientSocket.getInputStream()));
            // Wrap the output stream in a BufferedWriter.
            writer = new BufferedWriter(
                            new OutputStreamWriter(clientSocket.getOutputStream()));
            game.setWriter(writer);
            game.startNewGame();

            // Read lines until the client terminates.
            String request = reader.readLine();
            while(request != null){
                // Write the length of the line as a String.
                playerCommand(request);
                request = reader.readLine();
            }
            }
            catch(IOException e){
            System.out.println("IOException talking to the client: "+
                       e.getMessage());

            }
            finally{
            if(clientSocket != null){
                System.out.println("The client has gone.");
                break;
                // Close the socket to the client.
                //try
                //  {
                //      clientSocket.close();
                //  }
                //catch(Exception e)
                //  {
                //      System.out.println("Error" + e.getMessage());
        //                  System.exit(1);
                //                  }
            }
            }
           try
                {
                serverSocket.close();
                }
             catch(Exception e)
                {
                    System.out.println("Error" + e.getMessage());
                System.exit(1);
                }

        }
        }           
    };
    serverThread.start();   
}
}


protected ServerSocket getServerSocket(){
return serverSocket;
}

// The socket on which the listening is done.
private final ServerSocket serverSocket;

1 个答案:

答案 0 :(得分:3)

这与clientSocket final没有任何关系。您的问题是您正在关闭客户端线程中的serverSocket。您应该只在线程的末尾关闭clientSocket:

while (!quit) {
    try {
       ...
    } catch(IOException e){
       System.out.println("IOException talking to the client: "+
               e.getMessage());
    } finally {
       ...
       clientSocket.close();
    }
    // DON'T DO THIS: serverSocket.close();
}

只有在serverSocket抛出accept()时才会关闭Exception - 客户端线程根本不应该