在此MSDN页面上:
Sending and Receiving Data on the Client
建议使用以下方法关闭套接字的发送方:
shutdown(SOCK_ID, SD_SEND);
我为什么要这样?
也许我没有,它只是一个推荐?也许是为了节省记忆?也许是为了速度?
有没有人有想法?
答案 0 :(得分:3)
答案在shutdown()
文档中:
如果how参数为
SD_SEND
,则不允许后续调用send
函数。 对于TCP套接字,在接收方发送并确认所有数据后,将发送FIN
。...
要确保所有数据在关闭之前在已连接的套接字上发送和接收,应用程序应在调用
shutdown
之前使用closesocket
关闭连接。等待远程端已发送其所有数据并启动正常断开连接的通知的一种方法使用WSAEventSelect
函数,如下所示:
- 致电
WSAEventSelect
注册FD_CLOSE
通知。- 使用
shutdown
致电how=SD_SEND
。- 收到
FD_CLOSE
时,请调用recv
或WSARecv
,直到该功能成功完成并指示已收到零字节。如果返回SOCKET_ERROR
,则无法进行正常断开连接。- 致电
醇>closesocket
。等待远程端已发送所有数据并启动正常断开连接的通知的另一种方法是使用重叠的接收呼叫:
- 使用
shutdown
致电how=SD_SEND
。- 调用
recv
或WSARecv
,直到函数成功完成,并指示接收到零字节。如果返回SOCKET_ERROR
,则无法进行正常断开连接。- 致电
醇>closesocket
。...
有关详情,请参阅Graceful Shutdown, Linger Options, and Socket Closure。
部分
换句话说,至少对于TCP,调用shutdown(SD_SEND)
会通知对等方您已完成发送更多数据,并且很可能很快就会关闭您的连接。同样,同伴也会为你做同样的礼貌。这样,两个对等体都可以知道连接在两端都是有意关闭的。这称为正常断开连接,而不是中止或异常断开连接。
默认情况下,如果您不调用shutdown(SD_SEND)
,closesocket()
将尝试为您执行正常关机 UNLESS 已禁用套接字linger选项。最好不要依赖这种行为,除非你有充分的理由不这样做,否则你应该在致电shutdown()
之前自己致电closesocket()
。
答案 1 :(得分:2)
除以下情况外,这是不必要和多余的:
这是我在大约30年内遇到过的唯一案例:可能还有其他案例,但我并不知道。
答案 2 :(得分:1)
没有与在套接字上发送或接收操作相关联的特定资源,套接字可以使用也可以关闭。关闭的原因与资源管理无关。关闭套接字是实现所谓的优雅关闭协议,它允许通信双方实现连接正在关闭,并允许最小化数据丢失。