2016-11-05 90 views
1

如果我設置mSocket.setSoTimeout(1000);我得到獲得操作超時異常的套接字讀取

java.net.SocketTimeoutException:讀超時

mSocket.getInputStream().read()等待的二分之一,預計之後。

但是,如果我做mSocket.setSoTimeout(0);我得到

java.net.SocketException異常:操作超時

1分鐘左右(55秒了我的大部分運行的)等待的是後令人費解。

我曾嘗試在我的Mac OS El Capitan上增加sysctl tcp設置無濟於事。如果這些設置將超時限制在一分鐘左右,我應該像以前一樣得到相同的讀取超時異常。這個操作是什麼超時異常?

編輯:它可能值得一提的是,我故意使用pfctl關閉網絡,並且因爲我通過tcp使用websockets,我希望連接不會中斷,因爲有很長的超時時間,並且一旦將網絡連接到網絡再來一次。

堆棧跟蹤兩個例外是相同的,即

at java.net.SocketInputStream.socketRead0(Native Method) 
at java.net.SocketInputStream.read(SocketInputStream.java:150) 
at java.net.SocketInputStream.read(SocketInputStream.java:121) 
at java.net.SocketInputStream.read(SocketInputStream.java:203) 
at org.jwebsocket.kit.WebSocketProtocolAbstraction.protocolToRawPacket(WebSocketProtocolAbstraction.java:220) 
+0

當您切斷網絡時,有沒有正在進行的發送? – EJP

+0

是的,很可能因爲我每秒發送1.5個信息。 – user3740387

回答

0

當應用程序調用setSoTimeout(0)然後OS實際上可能等待數據永遠。但是,不管SO_TIMEOUT值如何,有幾種事件會中斷讀取操作。

如果操作系統破壞套接字後面的TCP連接,則讀取操作會中斷,因爲TCP連接不再存在,並且將來也沒有機會接收任何數據。即使對方稍後發送了一個數據,本地TCP堆棧也會丟棄它(並且可能回答TCP-RST)。

操作系統銷燬了TCP連接,因爲它發送了數據並沒有收到任何ACK。因此,操作系統試圖重新傳輸數據,並在過了一段時間後放棄並摧毀了連接。

+0

至於有幾種事件可能會中斷讀取的第一個參數,如果打破此讀取的事件僅在網絡關閉後54-56秒後發生,我懷疑該數字是可配置的。任何猜測這個事件可能是什麼? – user3740387

+0

對於第二點,「操作系統銷燬了TCP連接,因爲它發送了數據並且沒有收到任何ACK。」我曾嘗試使用sysctl操縱系統變量無濟於事。由於其他人已經成功地獲得了更大的無響應但仍然存在連接的情況,我可能會做錯什麼。 1分鐘沒有反應似乎太短的時間來打破tcp。 – user3740387