2012-03-21 43 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

相關問題