关闭vs关闭套接字?

关闭vs关闭套接字?

在C中,我理解如果我们关闭套接字,则意味着套接字将被销毁,以后可以重新使用。

关机怎么样?描述说它关闭了与该套接字的双工连接的一半。但是那个套接字会像close系统调用一样被销毁吗?


大话西游666
浏览 680回答 3
3回答

慕虎7371278

这在Beej的网络指南中有解释。 shutdown是一种在一个或两个方向上阻止通信的灵活方式。当第二个参数是时SHUT_RDWR,它将阻止发送和接收(如close)。但是,close是实际销毁套接字的方法。有了shutdown,您仍然可以接收同伴已经发送的待处理数据(感谢Joey Adams注意到这一点)。

慕田峪7331174

现有的答案都不告诉人们如何shutdown以及close在TCP协议级别的作品,所以它是值得添加此。标准TCP连接通过4路终结终止:一旦参与者没有更多数据要发送,它就会向另一个发送FIN数据包另一方返回FIN的ACK。当另一方也完成数据传输时,它会发送另一个FIN数据包初始参与者返回ACK并完成传输。但是,还有另一种“紧急”方式来关闭TCP连接:参与者发送RST数据包并放弃连接另一方收到一个RST,然后放弃连接在我使用Wireshark进行的测试中,使用默认套接字选项,shutdown将FIN数据包发送到另一端,但确实如此。在另一方向您发送FIN数据包之前,您仍然可以接收数据。一旦发生这种情况,您Receive将获得0大小的结果。因此,如果您是第一个关闭“发送”的人,则应在完成数据接收后关闭套接字。另一方面,如果close在连接仍处于活动状态时进行呼叫(另一方仍处于活动状态,并且系统缓冲区中可能还有未发送的数据),则会将RST数据包发送到另一端。这有利于错误。例如,如果您认为对方提供了错误的数据或拒绝提供数据(DOS攻击?),您可以立即关闭套接字。我对规则的看法是:考虑shutdown之前close可能当如果在决定关闭之前完成了接收(接收的0大小数据),请在最后一次发送(如果有)完成后关闭连接。如果要正常关闭连接,请关闭连接(使用SHUT_WR,如果您不关心在此之后接收数据,也使用SHUT_RD),并等待直到收到0大小的数据,然后关闭插座。在任何情况下,如果发生任何其他错误(例如超时),只需关闭套接字即可。SHUT_RD和SHUT_WR的理想实现以下未经过测试,信任风险自负。但是,我相信这是一种合理而实用的做事方式。如果TCP堆栈仅通过SHUT_RD接收关闭,则应将此连接标记为不再需要数据。任何挂起和后续read请求(无论它们处于哪个线程)都将返回零大小的结果。但是,连接仍然是活动的和可用的 - 例如,您仍然可以接收OOB数据。此外,操作系统将删除它为此连接接收的任何数据。但就是这样,没有包裹会被发送到另一方。如果TCP堆栈仅通过SHUT_WR接收关闭,则应标记此连接,因为不能再发送数据。所有挂起的写入请求都将完成,但后续写入请求将失败。此外,FIN数据包将被发送到另一侧以通知他们我们没有更多数据要发送。

拉风的咖菲猫

close()如果使用shutdown()相反的话,可以避免一些限制。close()将终止TCP连接上的两个方向。有时您想告诉另一个端点您已完成发送数据,但仍希望接收数据。close()递减描述符引用计数(在文件表条目中维护并计算当前打开的引用文件/套接字的描述符的数量),如果描述符不为0,则不关闭套接字/文件。这意味着如果要分配,只有在引用计数降为0后才会进行清理。shutdown()一个可以启动正常的TCP关闭序列,忽略引用计数。参数如下:int shutdown(int s, int how); // s is socket descriptorint how 可:SHUT_RD或0 进一步接收是不允许的SHUT_WR或者1 不允许进一步发送SHUT_RDWR或者2 不允许进一步发送和接收
打开App,查看更多内容
随时随地看视频慕课网APP