Socket 关闭 VS Socket 关闭

我最近看到了一段类似于下面这样的代码(袜子当然是一个套接字对象) :

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

在套接字上调用关闭然后关闭它的确切目的是什么?如果有区别的话,这个套接字将用于非阻塞 IO。

218467 次浏览

这里有一个 解释:

一旦不再需要套接字, 调用程序可以丢弃 套接字通过应用关闭子例程 到套接字描述符。如果 可靠的传输插座有数据 当结束的时候 地方,系统继续尝试 数据传输。但是,如果数据是 仍然没有交付,系统丢弃 资料 程序对任何挂起都没有用处 数据,它可以使用关机 之前套接字上的子例程 关门。

关闭和关闭说明: 优雅关机(msdn)

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

省略关闭可能会导致套接字在 OS 堆栈中逗留,直到连接被正常关闭。

我的名字’关闭’和’关闭’是误导,’关闭’和’破坏’将强调他们的差异。

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

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

当你调用 close时,它会将句柄数减少一,如果句柄数达到零,那么套接字和相关连接将通过正常的关闭过程(有效地向对等端发送 FIN/EOF) ,套接字将被释放。

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

另一方面,调用 shutdown进行读写操作将关闭底层连接,并向对等方发送 FIN/EOF,而不管有多少进程具有到套接字的句柄。但是,它 没有释放套接字,然后您仍然需要调用 close。

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

这个很有用

1-缓冲冲洗

2-奇怪的错误检测

3-安全防护

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

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

无论如何,这是不可挽回的,所以你可以做你完全 发送你所有的数据,你想确保它至少在对等 操作系统缓冲器

上面的代码是不是错了?

在关闭调用之后直接进行的 close 调用可能会使内核无论如何都会丢弃所有传出的缓冲区。

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

它在套接字编程指南(Py2/Py3)中有提到

断开连接

严格地说,你应该使用 shutdown在一个套接字之前,你的 close它。 shutdown是对另一端套接字的通知。根据传递给它的参数,它可以表示“ 我不会再发了,但我还是会听的”或“ 我不听,谢天谢地!”。 然而,大多数套接字库都习惯于程序员忽略使用这种礼仪,因此通常 closeshutdown(); close()是相同的。 因此,在大多数情况下,不需要显式关闭。

...