当进程退出时,Windows 是否负责关闭套接字?

Sim*_*one 13 networking windows sockets

我已经阅读了关于 Linux 的这个问题,当进程终止时可以绑定端口吗?
Linux 似乎会在进程退出并留下打开的套接字后进行清理。我想知道是否有任何关于它如何在 Windows 上工作的规范。操作系统是否始终负责关闭不关闭就退出的进程的套接字?

use*_*686 10

在 Windows 和 Unixen 上,当进程退出时,内核会关闭所有打开的句柄。

视窗NT

终止进程– MSDN

终止进程有以下结果:

  • [...]
  • 进程分配的任何资源都将被释放。
  • 所有内核对象都已关闭。
  • [...]

当进程终止时,内核对象的打开句柄会自动关闭,但对象本身一直存在,直到它们的所有打开句柄都关闭为止。因此,如果另一个进程有一个打开的句柄,一个对象在使用它的进程终止后将保持有效。

ExitProcess功能– MSDN

退出进程会导致以下情况:

  • [...]
  • 进程打开的所有对象句柄都关闭。
  • [...]

Linux

exit(3) – Linux 程序员手册(libc 函数)

所有打开的stdio(3)流都被刷新和关闭。

_exit(2) – Linux 程序员手册(内核系统调用)

该函数_exit()“立即”终止调用过程。属于该进程的任何打开的文件描述符都将关闭;进程的任何子进程都由进程 1 init继承,并且进程的父进程被发送一个 SIGCHLD 信号。


请注意,在两个操作系统上,

  1. 套接字只是一种类型的文件描述符(fd)/内核对象,因此上述内容同样适用于文件和套接字。

  2. Unix 上的文件描述,以及Windows 上的对象句柄内核对象,可以被多个进程拥有——它们的句柄可以被子进程继承,甚至可以使用特殊的 IPC 函数传递。

  3. 文件或套接字只有在所有指向它的 fd 都被销毁时才会关闭。

  • TCP 套接字是一种特殊情况,因为它们的 TIME_WAIT 状态。例如,如果终止侦听 TCP 端口的应用程序,通常无法立即绑定到同一端口。 (2认同)
  • 不可以。文件 _descriptors_ 和对象 _handles_ 由 _one_ 进程拥有和访问,并且严格是 _per-process_ 实体。它是 [file _description_](http://pubs.opengroup.org/onlinepubs/007908799/xbd/glossary.html#tag_004_000_184) 和进程间共享的底层对象。 (2认同)

Dav*_*rtz 5

在 Windows 上,套接字是通信端点和进程之间的链接。这就是为什么当你复制一个套接字时,你会得到两个套接字但只有一个端点。这就是为什么您不能在不在另一个进程中创建新套接字的情况下将套接字从一个进程传递到另一个进程的原因。

如果进程不复存在,它的套接字必然不复存在。没有一个没有进程来保存它的套接字的概念。这就是为什么即使是希望在内核级别创建套接字的 Windows 内核驱动程序也必须指定一个进程来拥有该套接字或从可以拥有该套接字的进程上下文中调用该函数。(或者他们可以直接操作端点而不使用套接字。)

您的问题似乎真的不是关于套接字,而是关于通信端点本身。套接字具有对其通信端点的引用。当套接字消失时,引用计数下降。如果它达到零,则根据与端点关联的通信协议的要求,只要允许,就会将其删除。TCP 有一个 TIME_WAIT 状态,在此期间必须保留端点以处理任何“剩余”数据包。