我已经阅读了有关Linux的这个问题,当进程终止时可以绑定端口吗?
Linux 似乎会在进程退出并留下打开的套接字后进行清理。我想知道是否有关于这在 Windows 上如何工作的规范。操作系统是否会始终负责关闭未关闭套接字而退出的进程?
答案1
在 Windows 和 Unixen 上,当进程退出时内核会关闭所有打开的句柄。
视窗系统
终止进程–MSDN
终止进程会产生以下结果:
- [...]
- 该进程分配的所有资源都将被释放。
- 所有内核对象均已关闭。
- [...]
虽然内核对象的打开句柄会在进程终止时自动关闭,但对象本身会一直存在,直到所有打开的句柄都关闭。因此,如果另一个进程拥有该对象的打开句柄,则在使用该对象的进程终止后,该对象仍将保持有效。
ExitProcess
功能–MSDN退出进程会导致以下情况:
- [...]
- 该进程打开的所有对象句柄都已关闭。
- [...]
Linux
exit(3)
– Linux 程序员手册(libc 函数)全部开放标准输入输出(3)溪流被冲洗并关闭。
_exit(2)
– Linux 程序员手册(内核系统调用)该函数
_exit()
“立即”终止调用进程。所有属于该进程的打开的文件描述符都将被关闭;该进程的任何子进程都将被进程 1 继承,在里面,并向该进程的父进程发送SIGCHLD信号。
请注意,在两种操作系统上,
套接字只是文件描述符(fd)/内核对象的一种类型,因此上述内容同样适用于文件和套接字。
Unix 上的文件描述以及Windows 上的
对象句柄内核对象可以由多种的进程——它们的句柄可以被子进程继承,甚至可以通过特殊的 IPC 函数传递。文件或套接字仅在以下情况下关闭:全部指向它的 fd 已被销毁。
答案2
在 Windows 上,套接字是通信端点和进程之间的链接。这就是为什么当您复制套接字时,您会得到两个套接字但只有一个端点。这就是为什么您不能将套接字从一个进程传递到另一个进程,除非在另一个进程中创建新的套接字。
如果进程停止存在,其套接字也必然停止存在。没有进程来持有套接字,就没有套接字的概念。这就是为什么即使希望在内核级创建套接字的 Windows 内核驱动程序必须指定一个进程来拥有套接字,或者从可以拥有套接字的进程上下文中调用该函数。(或者他们可以不使用套接字而直接操作端点。)
您的问题似乎实际上不是关于套接字,而是关于通信端点本身。套接字具有对其通信端点的引用。当套接字消失时,引用计数会下降。如果它达到零,它将在允许的时间内尽快被删除,只要该端点与通信协议相关联。TCP 具有 TIME_WAIT 状态,在此期间必须保留端点以处理任何“剩余”数据包。
答案3
是的。从 Windows 3.1 95 98开始就是这样的 经验值(至少从 XP 开始我就确信这一点)。