socket.shutdown vs socket.close

Jas*_*ker 118 python sockets asynchronous

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

sock.shutdown(socket.SHUT_RDWR)
sock.close()
Run Code Online (Sandbox Code Playgroud)

在套接字上调用shutdown然后关闭它的目的究竟是什么?如果它有所不同,则此套接字用于非阻塞IO.

Rob*_*nes 229

调用close并对shutdown底层套接字有两种不同的效果.

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

当您调用close它时,句柄计数减1,如果句柄计数达到零,则套接字和关联连接将通过正常关闭过程(有效地向对等方发送FIN/EOF)并释放套接字.

这里需要注意的是,如果句柄计数未达到零,因为另一个进程仍然具有套接字的句柄,则连接未关闭且套接字未被释放.

另一方面,调用shutdown读取和写入会关闭底层连接并向对等方发送FIN/EOF,而不管有多少进程处理套接字.但是,它不会释放套接字,您仍然需要在之后调用close.

  • 用于读取的shutdown()是否会导致它发送FIN数据包?即关机(sock_fd,1); (2认同)
  • 总是调用 `.shutdown()` 并在下一行调用 `.close()` 是否明智?还是中间应该有延迟? (2认同)
  • @Luc然后只要没有其他进程有套接字句柄就关闭就好了. (2认同)

Bob*_*ler 36

这是一个解释:

一旦不再需要套接字,调用程序就可以通过对套接字描述符应用close子例程来丢弃套接字.如果可靠的传递套接字在关闭时具有与之关联的数据,则系统继续尝试数据传输.但是,如果数据仍未传送,系统将丢弃数据.如果应用程序对任何未决数据没有用处,它可以在关闭之前使用套接字上的shutdown子例程.


Dal*_*idy 17

关闭和关闭的说明:正常关闭(msdn)

关闭(在您的情况下)指示连接的另一端没有进一步的意图来读取或写入套接字.然后关闭释放与套接字关联的所有内存.

省略关闭可能导致套接字滞留在OS堆栈中,直到连接正常关闭.

IMO名称"关闭"和"关闭"具有误导性,"关闭"和"破坏"会强调他们的差异.

  • 它并不向另一端表明没有进一步阅读的意图。关闭读取不会向对等方发送任何内容。 (2认同)

myk*_*hal 6

它在套接字编程HOWTO中提到(py2/py3)

断开

Strictly speaking, you’re supposed to use shutdown on a socket before you close it. The shutdown 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 a close is the same as shutdown(); close(). So in most situations, an explicit shutdown is not needed.

...

  • 此信息不正确。只有在以下情况下才需要关闭用于写入的套接字:(1) 您已经分叉了该进程并且肯定希望*现在*发送 FIN,或者 (2) 您正在参与相互读取到 EOS 的协议,这样双方都可以同行同时关闭。否则“close()”就足够了。Python 文档应该更正。 (4认同)