当没有绑定侦听套接字但连接已打开时获取 EADDRINUSE 的语义是什么

当没有绑定侦听套接字但连接已打开时获取 EADDRINUSE 的语义是什么

考虑一个父进程完成 a socket/bind/accept,并将分叉子进程,并打开该套接字以供它们进行通信,同时父进程继续接受连接。然后该父进程被终止。

现在,另一个进程尝试在同一端口上绑定到父进程绑定到的同一地址,但收到 EADDRINUSE 错误。

但是,当您使用 完成此过程时sshd,似乎sshd 能够重新绑定到已关闭的端口,而在重新启动窗口期间(sshd 父进程未运行),不同的程序(以不同用户身份运行)只会获取 EADDRINUSE。

这背后的语义是什么?为什么可以sshd重新绑定,但另一个用户进程却不能?

此外,我可以确认netstat -a | grep PORT只有子进程运行期间(当其他进程不能运行时bind)的输出,唯一的连接是ESTABLISHED一个,没有处于LISTEN状态。

答案1

虽然我不理解所有的语义(我要么找错地方,要么缺少文档),但我相信在关闭连接后的一定时间内(可能由 设定SO_LINGER),没有进程可以打开一个具有相同详细信息的新套接字,除非它们已SO_REUSEADDR设置。

据我了解,这是为了防止有人在连接关闭后重新连接,并且该进程必须处理用于前一个进程的数据包。

man 7 socket没有记录这一点,SO_REUSEADDR这使得这个答案很难弄清楚。

相关内容