socket.shutdown vs socket.close
-
03-07-2019 - |
题
我最近看到了一些看起来像这样的代码(当然sock是一个套接字对象):
sock.shutdown(socket.SHUT_RDWR)
sock.close()
在套接字上调用shutdown然后关闭它的目的究竟是什么?如果它有所不同,则此套接字用于非阻塞IO。
解决方案
这是一个解释:
一旦不再需要套接字, 调用程序可以丢弃 通过应用close子例程来插入socket 到套接字描述符。如果一个 可靠的交付套接字有数据 在关闭时关联它 地方,系统继续尝试 数据传输。但是,如果数据是 仍未交付,系统丢弃 数据。应该应用 程序对任何待处理的程序都没用 数据,它可以使用关机 套接字之前的套接字 关闭它。
其他提示
调用 close
和 shutdown
对底层套接字有两种不同的影响。
首先要指出的是套接字是底层操作系统中的资源,多个进程可以拥有相同底层套接字的句柄。
当你调用 close
时,它会将句柄计数减1,如果句柄计数达到零,那么套接字和相关连接将通过正常关闭程序(有效地将FIN / EOF发送到peer)并且套接字被解除分配。
这里要注意的是,如果句柄计数没有达到零,因为另一个进程仍然有套接字句柄,那么连接没有关闭,套接字也没有被释放。
另一方面,调用 shutdown
进行读取和写入会关闭底层连接,并向对等方发送FIN / EOF,无论有多少进程处理套接字。但是,没有取消分配套接字,您仍然需要在之后调用close。
关闭和关闭的说明: Graceful shutdown(msdn)
Shutdown(在您的情况下)表示连接的另一端没有进一步的意图来读取或写入套接字。然后关闭释放与套接字关联的任何内存。
省略关闭可能导致套接字滞留在操作系统堆栈中,直到连接正常关闭。
IMO名称'关闭'和'关闭'具有误导性,'关闭'和'破坏'会强调他们的差异。
在Socket Programming HOWTO( py2 / < a href =“http://docs.python.org/3/howto/sockets.html#disconnecting”rel =“noreferrer”> py3 )
<强>断开强>
严格地说,在
关闭
之前,你应该在套接字上使用shutdown
。shutdown
是另一端套接字的建议。根据您传递的参数,它可能意味着&#8220; 我不再发送,但我仍然会听&#8221;或&#8220 ; 我不是在听,也不是在逃避!&#8221;。 然而,大多数套接字库都习惯于程序员忽略使用这种礼节,通常close
与shutdown()相同;关闭()代码>。 因此在大多数情况下,不需要显式关闭。
...
上面的代码不是错误的吗?
关闭调用后直接关闭调用可能会使内核丢弃所有传出缓冲区。
根据 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),强制套接字no发送更多数据
这在
中很有用1-缓冲区冲洗
2-奇怪的错误检测
3-安全防护
让我解释一下,当你从A发送数据到B时,不能保证 发送到B,它只保证被发送到A os缓冲区, 然后将其发送到B os缓冲区
因此,通过在A上调用shutdown(1),可以刷新A的缓冲区并引发错误 如果缓冲区不为空,即:数据尚未发送给对等方
无论这种情况是多么可以接受,所以你完全可以做到这一点 发送了所有数据,你想确保它至少在同行 os缓冲区