2011-04-17 81 views
6

我在寫C的IRC客戶端++,目前我有一個問題,即,在退出時,我做的:正常關閉TCP套接字

Send("QUIT :Quit\r\n"); // just an inline, variadic send() wrapper 
shutdown(m_hSocket, SD_BOTH); 
closesocket(m_hSocket); 

WSAShutdown(); 

然而,問題是,退出消息沒有被髮送。我嗅探了來自客戶端的數據包,事實上這個消息從未被髮送過。我相信這是套接字未被刷新的問題,但我不知道如何做到這一點,谷歌建議禁用Nagle的算法,但我懷疑這是好的做法。

在此先感謝。

+0

因爲當你得到這個工作時,請記住,一些IRC網絡將不會顯示自定義退出信息,直到您登錄> 5分鐘(實際長度因網絡而異)。這不是對你目前的問題的答案,但它是一個陷阱,可以在以後的混淆:) – 2011-04-17 22:59:51

+0

有趣的一點,但我已經爲它的幾個我們現在退出,仍然得到: 閱讀錯誤:連接重置由同行 – Saul 2011-04-18 00:07:08

+0

是的,我只是想我會提到它,因爲當你得到的插座問題修復:) – 2011-04-18 05:14:55

回答

5

首先,您應該檢查返回值send:您嘗試發送的數據實際上是否被網絡堆棧接受? (通常這應該在每個send呼叫之後完成,而不僅僅是在這種情況下)。

假設數據被接受,那麼AFAIK實際上應該通過調用shutdown來傳輸。您可以嘗試使用SO_LINGER來查看它是否有所作爲,請參見Graceful Shutdown, Linger Options, and Socket Closure on MSDN

+0

即使在該MSDN文章的註釋中使用該修復,在關閉退出時的套接字時仍然會出現錯誤。看起來WSACleanup()導致它。無論如何Jon! :D – Saul 2011-04-18 00:45:09

+7

在調用'shutdown()'之後,在遠程節點通過在循環中調用'recv()'來確認斷開請求之前,不應該調用'closesocket()'知道何時調用'recv()'),直到它返回0(或一個錯誤)。 – 2011-04-19 20:33:09