在C语言中,我明白如果我们关闭一个套接字,这意味着套接字将被销毁,以后可以重新使用。
关闭怎么样?描述说它会关闭到该套接字的双工连接的一半。但是这个套接字会像关闭系统调用一样被销毁吗?
在C语言中,我明白如果我们关闭一个套接字,这意味着套接字将被销毁,以后可以重新使用。
关闭怎么样?描述说它会关闭到该套接字的双工连接的一半。但是这个套接字会像关闭系统调用一样被销毁吗?
当前回答
这在Beej的网络指南中有解释。关闭是一种在一个或两个方向上阻止通信的灵活方式。当第二个参数是SHUT_RDWR时,它将同时阻塞发送和接收(如close)。然而,close实际上是销毁套接字的方法。
在关闭状态下,您仍然能够接收到对等端已经发送的待处理数据(感谢Joey Adams注意到这一点)。
其他回答
这在Beej的网络指南中有解释。关闭是一种在一个或两个方向上阻止通信的灵活方式。当第二个参数是SHUT_RDWR时,它将同时阻塞发送和接收(如close)。然而,close实际上是销毁套接字的方法。
在关闭状态下,您仍然能够接收到对等端已经发送的待处理数据(感谢Joey Adams注意到这一点)。
这可能是特定于平台的,我有点怀疑,但无论如何,我所见过的最好的解释是在这个msdn页面上,他们解释了关机,逗留选项,套接字关闭和一般连接终止序列。
总之,使用shutdown在TCP级别发送关闭序列,使用close释放进程中套接字数据结构所使用的资源。如果在调用close时还没有发出显式的关闭序列,则会为您启动一个。
如果改用shutdown(),则可以避免close()的一些限制。
close()将终止TCP连接的两个方向。有时您希望告诉另一个端点您已经完成了发送数据,但仍然希望接收数据。
Close()减少描述符引用计数(维护在文件表项中,计数当前打开的引用文件/套接字的描述符数量),如果描述符不为0,则不关闭套接字/文件。这意味着如果您正在进行fork,则只有在引用计数降为0之后才会进行清理。使用shutdown()可以启动正常的TCP关闭序列,忽略引用计数。
参数说明如下:
int shutdown(int s, int how); // s is socket descriptor
Int如何:
SHUT_RD或0 不允许进一步接收
SHUT_WR或1 不允许进一步发送
SHUT_RDWR或2 不允许进一步发送和接收
Linux: shutdown()导致侦听器线程select()唤醒并产生错误。关闭();close ();会导致无尽的等待。
Winsock:反之亦然- shutdown()没有作用,而close()被成功捕获。
我还成功地在linux下使用shutdown()从一个pthread强制另一个pthread当前阻塞在connect()提前中止。
在其他操作系统(至少是OSX)下,我发现调用close()足以让connect()失败。