2016-12-27 55 views
0

我在緩衝讀卡器連接TCP套接字,並在自己的線程的套接字上打開一個緩衝閱讀器的I/O,然後讀取使用的readLine數據時觸發異常:BufferedReader中在Java中失敗嘗試從封閉套接字讀取

try { 
    socket = new Socket(targetHost, targetPort); 
    ou = new PrintWriter(socket.getOutputStream(), true); 
    in = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

    while (true) { 
    message = in.readLine(); 
    ... 
    process the data 
    ... 
    } 
} catch (Exception e) { 
    e.printStackTrace(); 
    return; 
} 

只要連接存在,就可以正常工作。但是,當TCP連接的另一端意外消失時,在大約75%的情況下,該線程從未意識到對方已經消失,並且任何嘗試從緩衝讀取器讀取的操作都會產生一個「空」字符串,但沒有例外,我也無法關閉線程,因爲它不知道對方已經離開了。在大約25%的情況下,線程被終止(也沒有產生異常),但是產生期望的結果,我只需要線程在TCP連接斷開時消失。

我試圖用這個弄清楚,如果連接還活着:

boolean connected = socket.isConnected() && !socket.isClosed(); 

但是,這並不工作,當對方已經走了,線程不斷齧咬總是返回true。

任何想法的人?

+0

定義「消失」。 TCP連接的工作方式,如果另一端關閉連接,則應該看到異常。但是,如果另一端變得無法訪問(例如,拔下了電纜或關閉了服務器,則在TCP計算出錯誤之前會有很長的超時時間。 –

+0

離開意味着另一端的程序決定退出。不會崩潰,但退出。這意味着它關閉TCP連接。當連接被刪除,不應該有在客戶端檢測到的事件? – Balthasar

+1

它在哪裏說這應該拋出一個異常?爲什麼不您停止閱讀時'的readLine()'返回null,這意味着「流的末尾」,按的Javadoc?這就是「事件」你正在尋找。 – EJP

回答

2

的問題基本上是:「可以作爲設計的」。

讀者返回null,實際上是指:「沒有更多的數據,我在這裏做了。」

javadoc

返回:包含該行的內容,不包括任何行終止符或字符串空如果該流的末尾已到達

在其它單詞:關閉的套接字在此處被視爲「正常」操作;因此沒有例外。換句話說:您必須更改您的代碼以檢查readLine()的結果是否返回null;如果是這樣,你知道套接字已經消失了。

+0

但是,如上所述,TCP連接的另一端不僅僅是拔下,它關閉,即套接字關閉,應該有一個可檢測到的事件 – Balthasar

+2

@Bthathas有。 'readLine()'返回null。 – EJP

+1

@EJP謝謝。我正在尋找一個現有的問題,以dup結束,但沒有找到這個問題。另一方面,這兩個upvotes提升我超過25K。自由一臺!所以,我不介意。 – GhostCat

相關問題