2011-12-09 68 views
4

我在寫一個簡單的Java客戶端/服務器應用程序供我自己使用。它應該允許客戶端發送單行文本消息並閱讀多行響應。這種通信應該使用相同的連接重複多次。連續讀取來自套接字的所有輸入

這是我在客戶端讀取回應:

BufferedReader input = new BufferedReader(new InputStreamReader(server.getInputStream())); 
String line; 
while ((line = input.readLine()) != null) { 
    // processing here 
} 

的問題,這是的readLine()塊,一旦服務器發送的第一反應背部和客戶端無法發送,因爲新的消息那。這是可以理解的。一個天真的解決方法可能是通過發送某種已知的特殊字符串值,使客戶端識別並結束讀取循環,從而使服務器指示其輸出結束。但是,這個問題有更好的解決方案嗎?

+1

你的邏輯似乎沒問題,當你得到一個連接你等待一整行到達,處理它,然後等待下一行。這正是你所描述的你想要的。如果您只想讀一行,請刪除一行,但您想要做什麼? –

+1

處理這個問題的通常解決方案是兩個異步線程;其中一個讀取,另一個寫入,並且主線程繼續處理GUI。你可以在隊列上構建東西,這樣GUI就可以將消息添加到寫入線程可以在空閒時立即發送的隊列中。 – Stmated

+1

@RogerLindsjö:我想讀取所有行,然後發送一條新消息,然後再次讀取所有行併發送一條新消息......問題在於readLine塊。 – Ree

回答

1

我不會依靠readLine作爲主循環,因爲readLine依賴於「未來」數據(CR,或LF或CR + LF,如果已達到流尾,則返回null)。因此,如果CR之後沒有LF,BufferedReader就會陷入困境。這個readLine方法更適合讀取文件內容。

在你的情況,我會一次讀一個字符用

while ((myChar = input.read()) != -1) { 
    // processing here, storing information in a buffer and taking appropriate actions if 
    // A CR or LF is found 
} 

但是,即使這種行爲是可疑的,因爲一個Unicode字符可以超過一個字節,所以流可以被卡住,如果第一字節被髮送而不是第二個。你確定你的通訊是Unicode嗎?如果不是,則InputStreamReader更合適。

4

因爲你的客戶端應該讀取相同的連接多個多響應和處理響應的每個塊, 這可能是你的情況下非常有用:

BufferedReader input = new BufferedReader(new InputStreamReader(server.getInputStream())); 
    String line; 
    StringBuilder sb = new StringBuilder(); 
    while ((line = input.readLine()) != null) { 
     if (line.equals("~~/START/~~")) 
      sb = new StringBuilder(); 
     else if (line.equals("~~/END/~~")) { 
      doSthWithParagraph(sb.toString()); 
      sb.delete(0, sb.length()); 
     } else 
      sb.append(line); 
    } 

您可以使用自己的特殊字符串來識別開始,每個消息塊的結尾。

相關問題