2011-04-17 100 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