socket.shutdown vs socket.close

时间:2009-01-03 20:37:55

标签: python sockets asynchronous

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

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

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

7 个答案:

答案 0 :(得分:219)

调用closeshutdown会对底层套接字产生两种不同的影响。

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

当你调用close时,它会将句柄计数减1,如果句柄计数达到零,那么套接字和相关连接将通过正常的关闭程序(有效地向对等体发送FIN / EOF)和套接字被解除分配。

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

另一方面,调用shutdown进行读写会关闭底层连接,并向对等方发送FIN / EOF,而不管有多少进程有套接字句柄。但是,没有取消分配套接字,您仍然需要在之后调用close。

答案 1 :(得分:35)

这是一个explanation

  

一旦不再需要套接字,   调用程序可以丢弃   通过应用close子例程来插入socket   到套接字描述符。如果一个   可靠的交付套接字有数据   在关闭时关联它   地方,系统继续尝试   数据传输。但是,如果数据是   仍未交付,系统丢弃   数据。应该应用   程序对任何待处理的程序都没用   数据,它可以使用关机   套接字之前的套接字   关闭它。

答案 2 :(得分:18)

关闭和关闭的说明:Graceful shutdown (msdn)

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

省略关闭可能导致套接字滞留在操作系统堆栈中,直到连接正常关闭。

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

答案 3 :(得分:7)

在Socket Programming HOWTO(py2 / py3)中提到了

  

<强>断开

     

严格地说,你应该在shutdown之前在套接字上使用close。   shutdown是另一端套接字的建议。根据您传递的参数,它可能意味着“我不会再发送了,但我仍然会听”,或者“我不是在听,很好的摆脱! ”。   然而,大多数套接字库都习惯于程序员忽略使用这种礼仪,通常closeshutdown(); close()相同。   因此在大多数情况下,不需要显式关闭。

     

...

答案 4 :(得分:5)

上面的代码不是错误的吗?

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

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

答案 5 :(得分:4)

答案 6 :(得分:2)

Shutdown(1),强制套接字no发送更多数据

这在

中很有用

1-缓冲区冲洗

2-奇怪的错误检测

3-安全防护

让我解释一下,当你从A发送数据到B时,不能保证 发送到B,它只保证被发送到A os缓冲区, 然后将其发送到B os缓冲区

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

无论这种情况是多么可以接受,所以你完全可以做到这一点 发送了所有数据,你想确保它至少在同行 os缓冲区