簡體   English   中英

如何使用Java套接字檢測數據丟失?

[英]How to detect dataloss with Java sockets?

我有以下情況:使用“經典” Java服務器(使用ServerSocket)我想(盡可能快地)檢測到與客戶端的連接意外失敗(即,非優雅地/沒有FIN數據包)。

我模擬的方式如下:

  • 我在Linux機器上運行服務器
  • 我用telnet連接到盒子
  • 連接成功后,在框的防火牆中添加“ DROP”規則

發生的情況是發送數據在大約10k之后阻塞。 我不知道待了多久,但我已經等了十多分鍾了。 到目前為止,我研究了什么:

  • Socket.setSoTimeout-但是,這僅影響讀取。 如果只有寫,則沒有效果
  • 由於PW吞沒了異常,因此使用PrintWriter.checkError()檢查錯誤-但是,它永遠不會返回true

如何檢測到此錯誤情況,或者至少配置超時值? (在JVM或OS級別)

更新 :〜20分鍾后,在PrintWriter上,checkError返回true(使用CentOS計算機上的服務器JVM 1.5)。 該超時值在哪里配置?

〜20分鍾超時是由於Linux中的標准TCP設置。 除非您知道自己在做什么,否則與他們混為一談真的不是一個好主意。 我有一個類似的項目正在工作,我們正在通過斷開網絡電纜來測試連接丟失,結果就像您所看到的一樣,它會長時間掛起。 我們嘗試弄亂下面的TCP設置,這使超時更快,但是它在其他應用程序中造成了副作用,這些應用程序在不應該建立連接的情況下會斷開連接,這是由於繁忙時網絡延遲很小。

net.ipv4.tcp_retries2
net.ipv4.tcp_syn_retries

如果查看手冊頁中的tcp(man tcp),則可以了解這些設置的含義,並可能找到其他可能適用的設置。 您可以直接在/ proc / sys / net / ipv4下設置它們,也可以使用sysctl.conf。 我們發現這兩個使發送/接收失敗更快。 嘗試將它們都設置為1,您會看到發送呼叫失敗的速度更快。 更改之前,請確保不取當前設置。

我要重申的是,您確實不應該弄亂這些設置。 它們會對操作系統和其他應用程序產生副作用。 最好的解決方案就像Kitson所說的那樣,使用心跳和/或應用程序級別超時。

還要研究如何創建一個非阻塞套接字,以使send調用不會像這樣阻塞。 盡管要記住,只要發送緩沖區中有空間,使用非阻塞套接字發送通常會成功。 這就是為什么在阻塞之前需要大約1萬數據的原因,即使您在此之前斷開了連接。

唯一確定的方法是生成應用程序級別的“檢查”,而不是依賴傳輸級別。 例如,雙向心跳消息,如果任一端未收到預期的消息,它將關閉並重置連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM