2011-02-01 25 views
1

我有我的基於TCP的客戶端軟件的有趣/惱人的情況,它是這樣的:有沒有辦法告訴操作系統刪除任何緩衝的外出TCP數據?

  1. 我的客戶端進程在筆記本電腦上運行,它是通過TCP連接到我的服務器進程(其通過LAN另一臺機器上運行)
  2. 不負責任使用者將以太網電纜從他的筆記本電腦,而客戶端發送TCP數據
  3. 客戶端進程繼續調用send(),還有一些附加的TCP數據,填補了OS的SO_SNDBUF緩衝區,直到...
  4. 通知客戶端進程(通過MacOS/X的SCDynam icStoreCallback功能)以太網接口關閉,並通過調用close()在其TCP套接字
  5. 2到5秒響應傳遞...
  6. 用戶插入以太網電纜回
  7. 客戶端進程通知該接口是備份,並自動重新連接到服務器

這一切都工作得很好......除了有通常也不必要的步驟8中,這是這樣的:

0.8。在步驟4中close()'d的TCP套接字恢復(!)併發送內核的出站數據緩衝區中用於該套接字的其餘數據。發生這種情況是因爲操作系統在釋放套接字之前嘗試傳遞所有出站TCP數據......通常是件好事,但在這種情況下,我寧願這種情況沒有發生。

所以,問題是,有沒有辦法告訴TCP層將數據放入其SO_SNDBUF?如果是這樣,我可以在第4步關閉()死亡套接字之前完成該調用,並且在舊套接字被放棄後,我不必擔心舊套接字中的殭屍數據到達服務器。

+1

這聽起來像是蘋果執行中的一個錯誤。你*可以*將SO_LINGER設置爲0,這將消除調用關閉和實際發生關閉之間的等待。 'close'成功後,不應再傳輸數據。 http://www.unix.org/single_unix_specification_v3/ – 2011-02-01 02:58:42

+2

@Jerry Coffin:通過`send()`調用傳輸的數據不應該被接受*,但之前寫入的數據仍應該被傳輸。 – caf 2011-02-01 03:34:50

回答

1

這個(從兩個不同的TCP連接接收的數據並不相互排列)是TCP/IP的基本屬性。你不應該試着通過清除發送緩衝區來解決它 - 這是脆弱的。相反,您應該修復應用程序以在應用程序層處理這種可能性。

例如,如果您在服務器端從您認爲已連接的客戶端接收到新連接,則應該刪除現有連接。

此外,該過程的第4步有點可疑。實際上,您應該等到TCP報告錯誤(或者連接上發生應用程序級超時) - 正如您已經注意到的那樣,如果物理斷開只是短暫的,TCP將會恢復。

0

如果您想在步驟4關閉套接字時丟棄等待傳輸的任何數據,則只需在關閉前將SO_LINGER設置爲0。

相關問題