2011-12-07 80 views
0

當我的兩個守護進程互相對話時,我的套接字卡在close_wait中。在閱讀了關於這個主題的不同問題和博客文章之後,我證實我正在關閉來自雙方(發起者和接收者)的套接字。插槽卡在CLOSE_WAIT

模型去如下:

發件人: 建立連接,發送數據,等待確認,關閉連接

接收機: 接收連接,讀取數據,發送確認,關閉連接

任何人都可以告訴我我做錯了什麼嗎?注意:我正在使用close()來關閉連接。我已經嘗試使用關機,它並沒有改變的事情。任何提示將不勝感激。

編輯: 關閉套接字後不久,接收守護進程分叉。我試圖將文件描述符傳遞給在子進程中分叉並明確關閉它的函數,但是這並沒有解決我的問題。還有其他方式可以影響這個過程嗎?請注意發送守護進程不分叉。

+0

你的意思'TIME_WAIT'狀態? – sarnold

+0

你是什麼意思「卡住」?整個過程需要花費幾分鐘時間才能回收。如果您想避免等待,請通過'setsockopt'使用SO_REUSEADDR。 – Duck

+0

@Duck - 被卡住我的意思是我快速地看到其他套接字打開和關閉(不再出現在netstat的輸出中),但是一組連接打開並無限期地進入CLOSE_WAIT狀態。我已經看了5分鐘左右,他們似乎並沒有接近。他們現在堅持了10分鐘。我認爲他們永遠不會離開。 – dbeer

回答

1

在尋找的Wireshark之​​後,我看到最後說FIN_ACK:

「[TCP ACK的丟失段] [TCP前一段丟] ...」

事實證明,我的問題是造成通過讓兩個守護進程在同一個盒子上運行(我們添加了用於測試的東西)。在多個盒子上再次嘗試之後,我們不再遇到這個問題。

0

當你有一個打開一個套接字的應用程序,並且在做了一些發送接收之後,它從它的對等體接收一個FIN,從該狀態開始它進入CLOSE_WAIT狀態。它可以永遠保持這種狀態,直到你明確地調用close()。希望你實際上在close()中傳遞了正確的FD。

+0

正如我的問題所述,我明確地調用close()。我不相信我的文件描述符可能是錯的。看到我對其他答案的評論。 – dbeer

0

在我的(短)經驗中,您很可能會關閉錯誤的f​​d,甚至根本沒有達到「close」聲明。我偶然發現了後面的一個,第一個線索是我的應用程序變成了殭屍而不是關閉(特別是一個簡單的printf,在close語句使它全部下到地獄之前)。

可能值得您花時間檢查任務管理器/作業/系統監視器/ <某些與您的操作系統相關的進程視圖名稱>。

+0

我在說兩個守護進程。他們不停止跑步,所以我認爲他們不會成爲殭屍。至於錯誤的文件描述符,我看不出這是怎麼可能的。代碼如下:fd = open_socket(); send_info(fd,info); read_reply(fd,&ret); close(fd);我沒有看到它可以改變的任何方式。 – dbeer

0

其實這些都是在多線程服務器應用見證了相當普遍的問題 有兩件事情,你可以做些什麼來解決這個問題:

  1. 使用FD_CLOSEXEC上的插座。
  2. 使用setsockopt並在套接字上設置tcp_keepalive。

實現上述兩種解決方案的代碼在* NIX和Microsoft上可能有點不同。區別僅在於語義差異。

我建議實施上述兩項措施。

但是如果你不能修改代碼,那麼你可以使用 libkeepalive