2009-11-01 174 views
2

我有一個應用程序處理多種Java套接字連接到不同種類的遠程機器(某些PC,其他是嵌入式設備)。這些套接字和流不應該無限期關閉,除非有一個很好的原因(例如遠程系統崩潰)。Java套接字流意外終止

我經常遇到,其中輸入流意外結束,不需要任何理由(值是-1),即在遠程機器並不表示一連接中止的問題。但是,當我放棄這些-1讀取並繼續從流中讀取時,遠程機器實際上稍後會發送新數據。這可能會持續很長時間。我也可以寫入輸出流。

在當前形勢下,我有治療-1作爲流的末尾之間的選擇和關閉套接字(誤報),或忽略-1投入和風險尚未收到通知的真正斷開的。

我一直沒能創造這一問題的工作示例和出現的問題隨機。

任何想法有什麼不對?

修改爲添加: Java端點是對現有VB應用程序的重寫,沒有這些問題(至少據我所知)。

+2

我認爲在你的源代碼中窺視會有所幫助。 – 2009-11-01 13:57:17

+1

謝謝,但正如我所說,我還沒有創建一個簡單的,工作的問題的例子,整個事情是太多的代碼。 – 2009-11-01 14:36:23

+0

「太多代碼」,可能是您的問題的一部分。它不應該那麼複雜。 – 2009-11-01 16:03:27

回答

0

檢查路由器是否正常。廉價路由器,特別是那些做NAT的人,通常會偶爾清理它們的連接表,導致連接失效。

在任何情況下,你的應用程序應該是對這些東西(他們會再次發生)強大的,你可能會不經商業價值跨線regularily發送數據包幫助它。

+0

我是。 「保持活着」消息被定義和使用,但沒有幫助。 當我在同一臺機器上運行服務器和客戶端時,問題也出現了。 – 2009-11-01 13:43:40

+0

另外,正如我所說的,如果我忽略-1,它至少在幾個小時內就像一個魅力。 – 2009-11-01 13:46:29

-1

您的環境中顯然存在一些網絡問題,您可以嘗試跟蹤它們,但暫時更安全關閉流並重新打開它。這就是API所承擔的。

+0

'網絡問題'不會導致'read()'返回-1。唯一可能導致的結果就是法定FIN分段的接收。 – EJP 2017-05-06 10:38:17

0

你有沒有使用過Wireshark?它非常容易設置,並且可能會讓你知道在發生這種情況時TCP會話是否有任何異常。

我有類似的東西,你的問題,曾經和我通過發送ping消息服務器和客戶端之間的每一分鐘解決它。 (後來事實證明,如果沒有流量超過10分鐘,防火牆問題偶爾會關閉一半的連接。)

我知道你在做KeepAlive消息,但它沿途的東西可能是不支持他們。如果您用幾個字節發送自己的ping消息,則可以確定。在任何情況下,我都會使用Wireshark捕獲兩端的實際數據包,以確保KeepAlive消息確實能夠一直通向終端。

+0

我沒有發送tcp keepalive,它是Thorbjørn建議的實際「空白」業務消息,以確保至少每隔十分鐘發送至少一條消息。較少是困難的,因爲整個事情也需要在相當昂貴的3G移動網絡上工作,所以我還需要保持低字節數。 – 2009-11-01 14:41:00

+0

啊,如果你發送真正的0字節的數據包從應用層到應用層,那麼我估計不是這樣。你可以用1分鐘的頻率試試它,即使這不是一個實際的產品解決方案。但是我也錯過了你說在同一臺機器上運行時發生了什麼。我會嘗試首先複製它。如果可能發生在同一臺機器上,那麼無需浪費時間使用wireshark和網絡。 – 2009-11-01 15:04:28

1

如果你得到-1意味着流被關閉,那麼你可以不讀超出這一範圍,尋找更多的數據。流關閉後,不能再次讀取。

這聽起來像你正在執行一個read()並將其轉換爲一個字節。這意味着你不能區分255值(你可以閱讀的更多)和-1流的封閉值(你不能)

+1

我不會將stream.read()操作的結果轉換爲字節。我知道這些文檔是怎麼說的。如果我只是忽略-1並且在100毫秒後再次嘗試讀取,並且無限期地重複,則新數據最終到達。這很瘋狂,但它確實有效。 – 2009-11-01 19:14:35

+0

這種行爲可能是在套接字之上分層流的結果(在操作系統級提供自己的流語義)。但是,鑑於Bug Parade沒有任何類似行爲的報告,我會在懷疑Java之前懷疑OP的代碼。 – kdgregory 2009-11-02 12:53:35