2011-08-26 123 views
2

我使用套接字在服務器和客戶端之間進行通信。 由於某些原因,客戶端會跳過服務器發送的每一行。BufferedReader readLine每隔一行跳過一次

客戶端的代碼:

... 

    out.println(console.readLine());    //Client initiates (sent to server) 

    while ((userOut = in.readLine()) != null)  //Waits for response 
    { 
     System.out.println("Server says: " + userOut); //Prints response 

     userIn = console.readLine();    //Gets user input 
     out.println(userIn);      //Sends user input to server 
    } 

    ... 

服務器代碼:

... 

    while ((clientIn = in.readLine()) != null) //Waits for clients message 
    { 
     System.out.println("Client says: " + clientIn); //Print clients message 

     //Send appropriate response 
     if (clientIn.equals(CLIENT_INSTRUCTION_LOGCALC)) 
     { 
      out.println(SERVER_RESPONSE_LOGCALC_OK); //Send response to client 
      System.out.println("Message sent: " + SERVER_RESPONSE_LOGCALC_OK); //Print response sent 
     } 

     else if (clientIn.equals(CLIENT_INSTRUCTION_SB)) 
     { 
      out.println(SERVER_RESPONSE_SB_CHANGE); 
     } 

     else if (clientIn.equals(CLIENT_INSTRUCTION_BYE)) 
     { 
      out.println(SERVER_RESPONSE_BYE_OK); 
     } 

     else if (clientIn.equals(CLIENT_INSTRUCTION_END)) 
     { 
      out.println(SERVER_RESPONSE_END_OK); 
     } 

     else 
     { 
      out.println(SERVER_RESPONSE_INPUT_ERR); 
     } 
     ... 

(第一客戶端)在使用本顯示器的一個例子:

LOGCALC 
Server says: LOGCALC: OK 
LOGCALC 
Server says: 

服務器:

Client says: LOGCALC 
Message sent: LOGCALC: OK 

Client says: LOGCALC 
Message sent: LOGCALC: OK 

希望您可以看到,在發送給服務器的第二條LOGCALC消息中,服務器做出了響應,但客戶端沒有收到服務器響應。

有什麼想法?

+0

但它確實收到迴應,不是嗎?否則「服務器說:」部分不應該出現。 –

回答

0

看着你的輸出,看起來你在SERVER_RESPONSE_LOGCALC_OK中有一個額外的換行符,因爲System.out.println("Message sent: " + SERVER_RESPONSE_LOGCALC_OK);在服務器輸出中有一個額外的行。我會刪除多餘的換行符或使用簡單的out.print(SERVER_RESPONSE_LOGCALC_OK)而不是out.println(SERVER_RESPONSE_LOGCALC_OK);。這應該可以解決你的跳過問題。

您遇到的根本缺陷是,因爲你只有一次讀取一行,然後等待用戶輸入讀取另一行,而不是儘可能多的行之前的等待用戶輸入之前是可用的。我敢打賭,如果你在客戶端執行類似下面的代碼,你會看到不同的輸出。

out.println(console.readLine());    //Client initiates (sent to server) 

    while ((userOut = in.readLine()) != null)  //Waits for response 
    { 
     System.out.println("Server says: " + userOut); //Prints response 

     if(!in.available()){ 
      userIn = console.readLine();    //Gets user input 
      out.println(userIn);      //Sends user input to server 
     } 
    } 
+0

available()不能用於此目的,因爲服務器回覆的某些部分可能會被網絡延遲。 – x22

+0

'available'完全按照它的說法:查看是否有可供讀取的數據。由網絡延遲的數據不可用。另一種方法是將網絡讀取循環移動到一個單獨的線程中,以便在控制檯readLine調用時阻止網絡套接字readLine調用。 – Femi

0

的readLine()

掃描爲\ r \ N,僅通過\ R或通過\ n只。

我認爲,服務器可能會通過\ n \ r-linebreak回答,在這種情況下,您將成爲您的雙重換行符(一個用於\ n,另一個用於\ r)。

據我所知,這可能不是您的代碼的功能問題。 因此,要跳過日誌記錄問題:您可以檢查空的userOut(通過空白檢查)。

1

客戶端肯定會收到「某些」類型的消息,因此印刷的「服務器說」部分。看起來,當向客戶端發送「第一響應」時,服務器以某種方式編寫了額外的新行,從而導致在第二次迭代中讀取空字符串。在第二種情況下,值得檢查/調試userOut的值。

此外,我不確定是否有意爲之,但在服務器輸出的情況下看到空行。假設它是所有輸出的發佈代碼片段,那麼額外的新行從哪裏來?