2013-03-01 14 views
0

我很困惑的TCP使用的應用程序的行爲。當在Internet上的TCP連接的一端的應用程序在套接字上調用close()時,close()返回。然而,在另一端,套接字上的write()並不表示TCP連接已關閉。 AFAIK,這種行爲與TCP規範不一致:除非和直到它從TCP連接的另一端收到確認(具體地說,活動端的TCP狀態不能轉出),否則活動的close()不應該返回TIME_WAIT_1,除非它從另一端收到適當的響應 - 此時write()在另一端應該錯誤返回)。什麼會導致活動TCP關閉返回而不通知被動端?

我在TCP連接的兩端之間發現故障的入侵防禦系統(IPS)時就已經看到了這種行爲。 IPS的製造商正在解決這個問題。

是否有其他可能發生此行爲的情況?

我的環境是Unix,C,ONC RPC和套接字。

+0

你確定連接沒有被關閉,應用程序只是不知道它,直到它執行'read()'/'write()'嗎?由於OS內核最終管理連接,'close()'實際上可以正常工作,在返回之前等待來自遠程的響應。但是,然後,遠程內核知道連接已關閉,但無法通知應用程序,直到稍後嘗試訪問該連接...您必須跟蹤數據包才能確定,我認爲... – twalberg 2013-03-01 18:01:12

+0

@twalberg TCP連接的被動關閉端在write()系統調用中,或者將很快調用write()。 – 2013-03-01 20:15:51

回答

0

您正在協議協議狀態轉換和API行爲。 RFC中沒有任何內容表示close()API不能返回到應用程序,並且協議操作異步繼續,而這正是Sockets API默認情況下發生的情況。如果有待處理的數據被髮送到套接字發送緩衝區,並且接收器速度很慢,則可能需要一段任意時間才能發送FIN。您可以通過使用套接字選項SO_LINGER設置逗留超時來改變這種情況,這會導致接近阻塞狀態,直到所有數據都已刷新或超時過期,但在實踐中很少使用。

+0

還有一些問題。客戶端沒有未完成的數據發送到服務器,並且套接字上的服務器的select()調用始終超時,而不是在套接字的客戶端close()後返回(select()只查找只讀:它不尋找寫入準備或例外)。 – 2013-03-07 17:02:35

相關問題