user506912
user506912

Reputation: 69

Java networking using threads, when one client leaves the other cannot communicate to the server

I'm trying to create a server in java which accepts clients. Currently, two clients can connect to the server. However, when one leaves the other client can no longer communicate with the server. I think the issue is that my clientSocket is created outside my thread, which means it must be declared as 'final' because I use an innerclass. However, if I move it into the thread it cannot create the clientSocket. Any ideas on how to fix this? Thanks in advance.

Comment: If I close the clientSocket when the client leaves it says "Broken Pipe" error because the clientSocket is final so it cannot be changed - ie the clientSocket is the same for both clients.

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;

Upvotes: 2

Views: 1429

Answers (1)

Gray
Gray

Reputation: 116888

No this has nothing to do with the clientSocket being final. Your problem is that you are closing the serverSocket in the client thread. You should be closing the clientSocket only at the end of the thread:

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();
}

The serverSocket should only be closed if accept() throws an Exception -- it should not be touched by the client thread at all.

Upvotes: 3

Related Questions