2011-05-26 70 views
12

我正在使用BufferedReader.readLine()方法來讀取來自遠程服務器(用C編寫且我無法訪問源代碼)的響應。插槽:BufferedReader readLine()塊

BufferedReader br = new BufferedReader(new InputStreamReader(in)); 
String line; 
while((line = br.readLine())!=null){ 
    [...] 
} 

但是它總是阻塞在最後一行直到它超時。所以我用下面的代碼:

int b; 
while(true){ 
    b = in.read; 
    [...] 
} 

和我發現閱讀的最後一個字節爲13的整數值,我認爲這是一個回車,對不對?

那麼爲什麼readLine方法阻止?服務器如何通常表示流達到了終點?謝謝。

+0

能否請您粘貼你使用的非阻塞代碼。我期待看到可以爲非阻塞輸入做些什麼 – 2017-02-11 08:16:42

回答

12

在網絡連接的情況下,當套接字關閉時流將被終止。

因此readLine()阻塞直到收到「行尾」或手動關閉連接是非常正常的。當readLine()接收到'13'值的最後一個字符時,該行被讀取,循環再次開始,等待下一行。

「最後一行」和其他行之間沒有區別。

爲了停止循環,您必須在某處手動關閉連接或等待超時。但是,如果沒有關於您的通信協議的更多信息,則無法對此做出更精確的描述。

+0

你是對的;代碼將等待\ r,然後記住跳過下一個換行符(如果有的話)。 – 2011-05-26 14:26:45

4

這取決於協議。如果服務器未關閉流,則readLine將阻塞,直到收到適當的行結束爲止。所以如果服務器從不發送適當的行結束,你就被阻止了。你也許應該使用更多的低級方法,並嘗試獲取協議文檔,或者對其進行反向工程。

1

確保該服務器代碼通過out.println()代替的out.print()

1

您可以擴展狀態時,如果你不使用空行:

while((line = br.readLine())!=null && line.length() > 0) { 
    // ... 
} 
+1

是的,正確的想法。你可以做的另一件事是使用消息結尾的特殊字符序列。聲明類似'EOM'= \ n \ n其中'EOM'是EndOfMessage – BQuadra 2014-01-09 11:53:26

+0

除readLine將阻塞,直到檢測到行結束或流關閉。 – 2017-11-10 19:50:37