2011-10-15 40 views

回答

1

使用套接字進行編程時有幾種「閉合連接」。 (我將使用BSD衍生的系統調用名稱爲套接字操作,我希望他們通過更改爲C#保持相似的名稱。)

  • 客戶端程序關閉使用shutdown()close()插座。發生這種情況時,TCP會發送一個FIN數據包到您的服務器。當您嘗試讀取超出客戶端發送的數據的最後一個字節時,這將在服務器中顯示爲封閉的套接字。下一個read()可能會引發異常或錯誤情況。 (因環境而異)。這種情況通常可用於輪詢式界面(如select(2)poll(2)),因此您的標準事件循環處理程序可以發現客戶端退出並處理它們。

  • 客戶端程序意外退出。在這種情況下,客戶端的TCP實現可能會發送FIN數據包,但它可能不在應用程序輸入分析器的「預期」位置。準備好處理零字節讀取或EOF讀取,這些讀取表明過早的應用程序終止。

  • 客戶端主機可能會意外死亡。在這種情況下,客戶端的TCP實現將無法發送FIN數據包到您的服務器,並且您將不會收到任何客戶端連接已終止的任何通知。您可以啓用TCP SO_KEEPALIVE套接字選項,但至少Linux的默認爲兩小時閒置一個全系統的時候發送存活探測之前。

    如果是系統自帶備份「快速」,你的申請將接受或TCP數據包RST響應或沉默如果stateful firewall被配置爲不匹配的允許或發起業務流DROP包。 RST的情況可以被檢測到類似於FIN數據包。丟棄的數據包的靜音只能通過應用級別的保活數據包方案檢測到。

因此,最好在您可以接受的時間範圍內構建某種應用級別保活ping包。 (例如,IRC使用PINGPONG包,以確保客戶端仍連接到服務器 - 檢查之間的時間是可配置的網絡管理員。)

多久你就會坪,有多少失敗的ping包間去接受很大程度上取決於您的應用程序 - 您可能願意在注意和移除斷開連接的客戶端之前等待20分鐘,或者您可能希望在僅僅二十秒後注意並移除斷開連接的客戶端。需要多長時間取決於工作環境(對於火星漫遊者來說20秒不起作用,但對於連接局域網的第一人稱射擊遊戲來說,可能需要十倍太長時間)以及可用於這種「管理開銷」的網絡帶寬。

3

假設你正在談論分層在TCP之上的協議,是的,它可能發生。 TCP不需要發送任何數據包來保持連接處於活動狀態。因此,如果關閉連接的數據包沒有連接到服務器,服務器可能會認爲客戶端仍然存在,即使客戶端已關閉連接很長時間。

因爲這是TCP的一個衆所周知的性能,每一協議層疊在TCP的頂部有考慮到這一點。所以如果你只是遵循協議,你就不會有問題。

唯一的例外是,如果該協議是非常糟糕的設計,或者如果你正在設計的協議。如果你正在設計協議,你有很多選擇。例如,您可以指定一端至少每隔10分鐘發送一種消息。如果20分鐘內沒有收到任何消息,您可以指定另一端關閉連接。

+0

簡單而簡潔。尼斯。 – sarnold

相關問題