我最近看到了一些看起来像这样的代码(当然sock是一个套接字对象):
sock.shutdown(socket.SHUT_RDWR) sock.close()
在套接字上调用shutdown然后关闭它的目的究竟是什么?如果它有所不同,则此套接字用于非阻塞IO.
调用close
并对shutdown
底层套接字有两种不同的效果.
首先要指出的是,套接字是底层操作系统中的资源,多个进程可以拥有相同底层套接字的句柄.
当您调用close
它时,句柄计数减1,如果句柄计数达到零,则套接字和关联连接将通过正常关闭过程(有效地向对等方发送FIN/EOF)并释放套接字.
这里需要注意的是,如果句柄计数未达到零,因为另一个进程仍然具有套接字的句柄,则连接未关闭且套接字未被释放.
另一方面,调用shutdown
读取和写入会关闭底层连接并向对等方发送FIN/EOF,而不管有多少进程处理套接字.但是,它不会释放套接字,您仍然需要在之后调用close.
这是一个解释:
一旦不再需要套接字,调用程序就可以通过对套接字描述符应用close子例程来丢弃套接字.如果可靠的传递套接字在关闭时具有与之关联的数据,则系统继续尝试数据传输.但是,如果数据仍未传送,系统将丢弃数据.如果应用程序对任何未决数据没有用处,它可以在关闭之前使用套接字上的shutdown子例程.
关闭和关闭的说明:正常关闭(msdn)
关闭(在您的情况下)指示连接的另一端没有进一步的意图来读取或写入套接字.然后关闭释放与套接字关联的所有内存.
省略关闭可能导致套接字滞留在OS堆栈中,直到连接正常关闭.
IMO名称"关闭"和"关闭"具有误导性,"关闭"和"破坏"会强调他们的差异.
它在套接字编程HOWTO中提到(py2/py3)
断开
Strictly speaking, you’re supposed to use
shutdown
on a socket before youclose
it. Theshutdown
is an advisory to the socket at the other end. Depending on the argument you pass it, it can mean "I’m not going to send anymore, but I’ll still listen", or "I’m not listening, good riddance!". Most socket libraries, however, are so used to programmers neglecting to use this piece of etiquette that normally aclose
is the same asshutdown(); close()
. So in most situations, an explicit shutdown is not needed....