在此 MSDN 页面上:
在客户端发送和接收数据 https://msdn.microsoft.com/en-us/library/windows/desktop/bb530747.aspx
它建议使用以下方法关闭套接字的发送端:
shutdown(SOCK_ID, SD_SEND);
我为什么要?
也许我不需要,这只是一个建议?也许是为了节省内存?也许是为了速度?
有人有想法吗?
答案就在shutdown() https://msdn.microsoft.com/en-us/library/windows/desktop/ms740481.aspx文档:
如果 how 参数是SD_SEND
,后续调用send
功能被禁止。对于 TCP 套接字,FIN
将在所有数据发送并被接收方确认后发送.
...
为了确保在关闭连接的套接字之前发送和接收所有数据,应用程序应该使用shutdown
调用前关闭连接closesocket
。等待远程端已发送其所有数据并启动正常断开连接的通知的一种方法是使用WSAEventSelect
功能如下:
- Call
WSAEventSelect
注册FD_CLOSE
通知。
-
Call
shutdown
with how=SD_SEND
.
- When
FD_CLOSE
收到,拨打电话recv
or WSARecv
直到函数成功完成并指示收到零字节。如果SOCKET_ERROR
返回,则无法正常断开连接。
- Call
closesocket
.
另一种等待远程端已发送其所有数据并发起优雅断开连接的通知的方法使用重叠接收调用,如下所示:
-
Call
shutdown
with how=SD_SEND
.
- Call
recv
or WSARecv
直到函数成功完成并指示收到零字节。如果SOCKET_ERROR
返回,则无法正常断开连接。
- Call
closesocket
.
...
有关详细信息,请参阅以下部分正常关闭、延迟选项和套接字关闭 https://msdn.microsoft.com/en-us/library/windows/desktop/ms738547.aspx.
换句话说,至少对于 TCP,调用shutdown(SD_SEND)
通知对等方您已完成发送更多数据,并且您可能很快就会关闭连接端。最好,同伴也会为你做同样的礼貌。这样,双方都可以知道两端的连接都被有意关闭。这被称为graceful断开连接,而不是abortive or abnormal断开。
默认情况下,如果你不调用shutdown(SD_SEND)
, closesocket()
将尝试为您执行正常关机UNLESS插座的linger https://msdn.microsoft.com/en-us/library/windows/desktop/ms739165.aspx选项被禁用。最好不要依赖这种行为,您应该始终调用shutdown()
打电话之前自己closesocket()
,除非你有充分的理由不这样做。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)