socket.shutdown与socket.close

我最近看到了一些看起来像这样的代码(当然,sock是一个套接字对象):

sock.shutdown(socket.SHUT_RDWR) sock.close() 

调用套接字closures然后closures它的目的是什么? 如果有所作为,这个套接字被用于非阻塞IO。

这里有一个解释 :

一旦套接字不再需要,调用程序就可以通过对套接字描述符应用一个closures的子程序来丢弃套接字。 如果一个可靠的交付套接字有数据关联发生时,系统将继续尝试数据传输。 但是,如果数据仍未传送,系统将丢弃数据。 如果应用程序没有使用任何挂起的数据,它可以在closures之前使用套接字上的shutdown子例程。

调用closeshutdown对底层套接字有两个不同的效果。

首先要指出的是,套接字是底层操作系统中的一个资源, 多个进程可以拥有相同底层套接字的句柄。

当你调用close它把句柄递减1,如果句柄数已经达到零,那么socket和相关的连接将通过正常的closures过程(有效地向对等体发送一个FIN / EOF)并且释放套接字。

这里需要注意的是,如果句柄计数没有达到零,因为另一个进程仍然有套接字的句柄,那么连接没有closures,套接字不被释放。

另一方面,读取和写入调用shutdownclosures底层连接,并发送一个FIN / EOF给对方,而不pipe有多less进程已经处理到套接字。 但是,它不会释放套接字,并且您仍然需要在之后closures。

closures和closures说明:正常关机(msdn)

关机(在你的情况下)表明连接的另一端没有进一步的意图读取或写入套接字。 然后closures释放与套接字相关的任何内存。

忽略closures可能会导致套接字在OS栈中逗留,直到连接正常closures。

国际海事组织的名称“closures”和“closures”是误导,“closures”和“摧毁”会强调他们的分歧。

它在Socket编程HOWTO( py2 / py3 )

断开

严格地说,在close它之前,你应该使用shutdown套接字。 shutdown是另一端的sockets的build议。 根据你通过它的论点,这可能意味着“ 我不会再发送,但我仍然会听 ”,或者“ 我没有听,很好的解脱! ”。 然而,大多数套接字库都习惯于忽略使用这种礼节的程序员,而这种礼节通常与shutdown(); close()是一样的shutdown(); close() shutdown(); close() 。 所以在大多数情况下,不需要显式closures。

有一些关机的风味: http : //msdn.microsoft.com/en-us/library/system.net.sockets.socket.shutdown.aspx 。 *尼克斯是相似的。

这个代码是不是错了?

closures调用后直接closures调用可能会使内核丢弃所有传出缓冲区。

根据http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable需要等待关机和closures直到读取返回0。;

关机(1),强制套接字不发送更多的数据

这是有用的

1-缓冲液冲洗

2-奇怪的错误检测

3-安全防范

让我来解释一下,当你从A发送数据到B时,不能保证发送到B,只能保证发送到A缓冲区,A缓冲区又把它发送到B缓冲区

因此,通过在A上调用shutdown(1),可以刷新A的缓冲区,如果缓冲区不为空,则会引发错误,即:数据尚未发送给对等

无论如何这是不可修复的,所以你可以在完全发送所有的数据之后做到这一点,并且要确保它在对等OS缓冲区中至less