2012-03-21 44 views
2

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

评论:如果我关闭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; 

回答

3

没有此无关与clientSocketfinal。您的问题是您正在关闭客户端线程中的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(); 
} 

如果accept()抛出ExceptionserverSocket只应关闭 - 它应该由客户线程都感动了。

+0

我曾经这样做过,但当客户端离开时,我得到了一个破碎管道错误。 – user506912 2012-03-21 15:15:33

+1

@ user506912 - 当然是你做的,因为管道被客户断开连接断开了。使用mjames专利异常处理 - 抓取,检查,忽略。 – 2012-03-21 15:17:46

+0

在代码中抛出一个破碎管道错误@ user506912? – Gray 2012-03-21 15:18:16

相关问题