我最近看到了一些看起来像这样的代码(当然 sock 是一个套接字对象):
sock.shutdown(socket.SHUT_RDWR)
sock.close()
在套接字上调用shutdown然后关闭它的目的到底是什么?如果有所不同,则此套接字用于非阻塞 IO。
我最近看到了一些看起来像这样的代码(当然 sock 是一个套接字对象):
sock.shutdown(socket.SHUT_RDWR)
sock.close()
在套接字上调用shutdown然后关闭它的目的到底是什么?如果有所不同,则此套接字用于非阻塞 IO。
调用close
和shutdown
对底层套接字有两种不同的影响。
首先要指出的是,套接字是底层操作系统中的一种资源,多个进程可以拥有同一个底层套接字的句柄。
当您调用close
它时,将句柄计数减一,如果句柄计数达到零,则套接字和关联的连接将通过正常的关闭过程(有效地向对等方发送 FIN / EOF)并释放套接字。
这里要注意的是,如果句柄计数没有达到零,因为另一个进程仍然有套接字的句柄,那么连接不会关闭,套接字也不会被释放。
另一方面,调用shutdown
读取和写入会关闭底层连接并向对等方发送 FIN / EOF,而不管有多少进程拥有套接字的句柄。但是,它不会释放套接字,您仍然需要在之后调用 close。
这是一种解释:
一旦不再需要套接字,调用程序可以通过对套接字描述符应用关闭子例程来丢弃套接字。如果在发生关闭时可靠的传递套接字具有与之关联的数据,则系统会继续尝试数据传输。但是,如果数据仍未交付,系统将丢弃该数据。如果应用程序对任何未决数据没有用处,它可以在关闭套接字之前使用套接字上的关闭子例程。
关闭和关闭的解释:Graceful shutdown (msdn)
关闭(在您的情况下)表明连接的另一端没有进一步读取或写入套接字的意图。然后关闭释放与套接字关联的所有内存。
省略关闭可能会导致套接字在操作系统堆栈中逗留,直到连接正常关闭。
IMO 名称“关闭”和“关闭”具有误导性,“关闭”和“销毁”会强调它们的区别。
上面这段代码是不是错了?
在关闭调用之后直接关闭调用可能会使内核丢弃所有传出缓冲区。
根据 http://blog.netherlabs.nl/articles/2009/01/18/the-ultimate-so_linger-page-or-why-is-my-tcp-not-reliable 需要在关机和关闭直到读取返回 0。
有一些关闭的味道:http: //msdn.microsoft.com/en-us/library/system.net.sockets.socket.shutdown.aspx。*nix 类似。
Shutdown(1) ,强制套接字不发送更多数据
这在
1- 缓冲区刷新
2-奇怪的错误检测
3- 安全防护
让我再解释一下,当您从 A 向 B 发送数据时,并不保证会发送到 B ,只保证会发送到 A os 缓冲区,然后再将其发送到 B os 缓冲区
因此,通过在 A 上调用 shutdown(1) ,您可以刷新 A 的缓冲区,如果缓冲区不为空,则会引发错误,即:数据尚未发送到对等方
但是,这是不可撤销的,因此您可以在完全发送所有数据之后执行此操作,并且您希望确保它至少在对等操作系统缓冲区中