2012-03-21 5 views
2

クライアントを受け入れるjavaでサーバーを作成しようとしています。現在、2つのクライアントがサーバーに接続できます。ただし、一方が離れたときにもう一方のクライアントはサーバーと通信できなくなります。問題は、私のclientSocketがスレッドの外に作成されていることです。つまり、内部クラスを使用するため、finalとして宣言する必要があります。しかし、それをスレッドに移すと、clientSocketを作成することはできません。どのようにこれを修正するための任意のアイデア?前もって感謝します。スレッドを使用したJavaネットワーキングは、あるクライアントが他のクライアントを離れるときにサーバーと通信できません。

コメント:clientSocketが最後であるため変更できません。つまり、両方のクライアントでclientSocketが同じであるため、クライアントが終了するときにclientSocketを閉じると "Broken Pipe"エラーが発生します。

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()Exceptionをスローした場合serverSocketにのみ閉鎖される必要があります - それはないは全くクライアントスレッドが触れるべきです。

+0

私はこれをしていましたが、クライアントが去ったときに壊れたパイプエラーが発生しました。 – user506912

+1

@ user506912 - もちろん、あなたがしたのは、パイプがクライアントの切断によって壊れてしまったからです。 mjamesの特許例外処理 - キャッチ、チェック、無視を使用する。 –

+0

どこに壊れたパイプエラー@ user506912を投げているコードですか? – Gray

関連する問題