2012-09-03 134 views
0
  1. 兩臺計算機通過套接字連接進行連接。如果服務器/客戶端從其末端關閉連接 (即關閉InputStream,OutputStreamSocket),那麼如何告知 關於斷開的另一端?有一種我知道的方法 - 試圖從InputStream, 中讀取,如果連接已關閉,則會拋出IOException,但有沒有其他方法可以檢測到?
  2. 另一個問題,我看着在互聯網上的問題,看到inputStream.available() 不能解決這個問題。這是爲什麼?

附加信息:我所要求的另一種方式,因爲我的項目變得很難處理,如果我必須嘗試從 InputStrem讀取檢測斷線。JAVA:處理插座斷開連接

+1

恩,不知道你希望如何解決這個問題。您仍然需要某種套接字讀取或寫入來確定它已關閉。 – Tudor

+0

思考如何做到這一點,以便在對方關閉時(正確關閉而不是斷開連接)立即通知它的套接字: 1)專用於讀取套接字並將數據放入容器以備將來使用的線程處理,例如。 ArrayBlockingQueue。當它找到-1或IOException時,它可以通過設置一個標誌,調用某種方法或在隊列中放置一個EOS標記來停止並通知其他線程通信已結束(或已被中斷)。 2)其他線程可以在需要時讀取隊列,並在需要時檢查該標誌。 –

+0

@SaintHill Allthat完全沒有增加你自己的閱讀。 – EJP

回答

6

試圖從InputStream讀取,從而拋出IOException

這是不正確的。如果對方關閉套接字:

  • read()返回-1
  • readLine()返回null
  • readXXX()拋出EOFException,任何其他X上

由於InputStream只有read()方法,它只返回-1:它不會在EOS中拋出IOException

與此處的其他答案相反,沒有TCP API或Socket方法會告訴您對等方是否已關閉連接。你必須嘗試閱讀或寫作。

您應該使用讀取超時。

InputStream.available()不能解決問題,因爲它不返回任何類型的EOS指示。它的正確用途很少,這不是其中之一。

0

問題不在於「如果服務器/客戶端關閉連接」。問題是「如果他們沒有關閉連接而連接被中斷?」

如果沒有自己的心跳協議,沒有辦法檢測到。

另一種選擇是將SO_KEEPALIVE設置爲true。

「當keepalive選項設置爲TCP套接字,並沒有數據已通過套接字在任一方向交換2小時(注:實際值與實現有關)」

在我的經驗,比每2小時快得多。更像一個~5分鐘。除了使用SO_KEEPALIVE,你是莊嚴擰:P

在我的通信協議,我用的是每2秒發送一個保留「心跳」字節。我自己的filterInputStream和filterOutputStream發送/並消化心跳字節。

+0

男人我笑你的答案:D –

+0

設置SO_KEEPALIVE什麼也不做,除非你做了讀或寫,而且如果對方關閉連接,它什麼也不做。這不是EOS測試,它是一種檢測被中斷的空閒連接的方式。 – EJP

+0

不,我明白了,我嘲笑那部分「你被大肆攻擊:P」 –

0

當連接斷開時,沒有O-O-O的方式來獲得回調/異常。只有當您在套接字流上進行明確的讀/寫操作時,纔會瞭解有關斷開的連接。

有兩種方法可以從套接字讀取即,在它們到達時逐字節地同步讀取;或等待直到流中可用的期望數量的字節,然後進行批量讀取。你可以通過在套接字流上調用available()來進行檢查,從而爲您提供當前可供讀取的字節數。在第二種情況下,如果套接字連接由於某種原因而中斷,則無法通知您。在這種情況下,您需要使用超時機制來等待。在第一種情況下,你明確地讀/寫你會得到一個異常。

+0

O-O-O與它無關。根本沒有辦法。調用'available()'的技術沒有任何推薦。這只是一個更復雜,更容易出錯的循環阻塞方式。 – EJP

0

Q1如果關閉服務器上的套接字連接,客戶端應該立即拋出一個異常,當然下一次嘗試就會拋出異常,反之亦然。

Q2從的JavaDoc

返回一個估計可以從該輸入流中讀取(或 跳過)的字節數的,而不受下一個 調用的方法的這個阻塞輸入流。下一個調用 可能是同一個線程或另一個線程。單個讀取或跳過 這麼多字節不會被阻塞,但可以讀取或跳過較少的字節。

這不是當前在流的字節數量的指示,但是可以從實現中讀取的字節數的估計值,這將不會阻止當前線程

+0

Socket.isClosed()不會告訴您對等端是否已關閉連接的結束。它會告訴你是否關閉了該套接字。 – EJP

+0

@EJP感謝te指針 – MadProgrammer

+0

客戶端不會拋出'IOException'。它*可能會拋出一個'EOFException',這取決於它所調用的讀取方法。 – EJP