2012-01-08 165 views
0

我寫了一個簡單的程序,服務器應該打印多個客戶端發送的數據。但服務器只接收部分數據。以下是代碼的相關部分。服務器不接收來自多個客戶端(java套接字)的數據

服務器:

try { 
     serverSocket = new ServerSocket(8888); 
    } catch (IOException e) { 
     System.err.println("Could not listen on port: 8888"); 
     System.exit(-1); 
    } 
while (listening) { 
    Socket clientSocket = serverSocket.accept(); 
    BufferedReader reader = new BufferedReader(new InputStreamReader(
          clientSocket.getInputStream())); 
     System.out.println(reader.readLine()); 

     reader.close(); 
     clientSocket.close(); 
    } 
    serverSocket.close(); 

客戶:

try { 
     socket = new Socket("nimbus", 8888); 
     writer = new PrintWriter(socket.getOutputStream(), true); 
     localHost = InetAddress.getLocalHost(); 
    } 
    catch (UnknownHostException e) {} 
    catch (IOException e) {} 

    StringBuilder msg1 = new StringBuilder("A: "); 
    for(int i=1; i<=3; i++) 
     msg1.append(i).append(' '); 
    writer.println(localHost.getHostName() + " - " + msg1); 

    StringBuilder msg2 = new StringBuilder("B: "); 
    for(int i=4; i<=6; i++) 
     msg2.append(i).append(' '); 
    writer.println(localHost.getHostName() + " - " + msg2); 

    StringBuilder msg3 = new StringBuilder("C: "); 
    for(int i=7; i<=9; i++) 
     msg3.append(i).append(' '); 
    writer.println(localHost.getHostName() + " - " + msg3); 

    writer.close(); 
    socket.close(); 

我得到下面的輸出(當3個客戶端上運行)

nimbus2 - A: 1 2 3 
nimbus3 - A: 1 2 3 
nimbus4 - A: 1 2 3 

我沒有得到第二和第三消息。服務器不斷等待。我哪裏錯了?

編輯:在服務器代碼中,我嘗試刪除reader.close()clientSocket.close()。那也行不通。另一個問題 - 如果3個客戶發送3條消息,是否需要9個連接? (這是原因,我關閉了服務器代碼中的連接)

回答

1

你可能想要將socket的處理委託給另一個線程。我寫了一個示例,它通過將每個傳入套接字傳遞給Executor以便讀取所有輸入。我使用了一個Executors.newCachedThreadPool(),它應該隨着需要增長。你也可以使用Executors.newFixedThreadPool(1),如果你希望它一次只能處理1個客戶端。

我做的唯一的其他改變是我刪除了BufferedReader並用掃描器替換了它。我遇到了BufferedReader沒有返回數據的問題。我不知道爲什麼。

Executor exe = Executors.newCachedThreadPool(); 
ServerSocket serverSocket = null; 
try { 
    serverSocket = new ServerSocket(8888); 
} catch (IOException e) { 
    System.err.println("Could not listen on port: 8888"); 
    System.exit(-1); 
} 
while (listening) { 
    final Socket clientSocket = serverSocket.accept(); 

    exe.execute(new Runnable() { 

     @Override 
     public void run() { 
      try { 
       Scanner reader = new Scanner(clientSocket.getInputStream()); 
       while(reader.hasNextLine()){ 
        String line = reader.nextLine(); 
        System.out.println(line); 
       } 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
      try { 
       clientSocket.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    }); 

} 
serverSocket.close(); 
+0

謝謝。看着你的代碼,我意識到我的服務器代碼的問題是缺少循環(用於讀取數據)。它添加循環後工作正常(和我使用BufferedReader) – Raghava 2012-01-08 18:30:17

+0

我很高興我可以幫助。如果您只是使用循環,則您的服務器一次只能處理來自一個客戶端的輸入。如果第二個客戶端在第一個客戶端仍在發送數據時連接,則第二個客戶端將被迫等待並可能超時。 – patheros 2012-01-08 19:52:51

+0

好的,謝謝你的投入:)。我會按照你的建議使用線程。 – Raghava 2012-01-08 19:54:33

0

看起來您可以在客戶端完成寫入之前關閉與客戶端的連接/在服務器讀取所有發送的消息之前。我認爲您需要繼續使用readline,並且可能不會在向您發送一條消息後終止客戶端的連接。

+0

我試過了,它也沒有工作 – Raghava 2012-01-08 16:28:56

0

約翰是對的。 通過讀取消息後調用clientsocket.close()來關閉客戶端連接,這就是爲什麼您無法獲取其他消息的原因。你應該在收到所有消息時調用clientsocket.close()

+0

我試過了,我刪除了clientSocket.close()以及reader.close()。它不起作用。會有其他原因嗎? – Raghava 2012-01-08 16:49:33

相關問題