我最近看到了一些看起来像这样的代码(当然sock是一个套接字对象):
sock.shutdown(socket.SHUT_RDWR)
sock.close()
在套接字上调用shutdown然后关闭它的目的究竟是什么?如果它有所不同,则此套接字用于非阻塞IO。
答案 0 :(得分:219)
调用close
和shutdown
会对底层套接字产生两种不同的影响。
首先要指出的是套接字是底层操作系统中的资源,多个进程可以拥有相同底层套接字的句柄。
当你调用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
是另一端套接字的建议。根据您传递的参数,它可能意味着“我不会再发送了,但我仍然会听”,或者“我不是在听,很好的摆脱! ”。 然而,大多数套接字库都习惯于程序员忽略使用这种礼仪,通常close
与shutdown(); 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缓冲区