使用SO_REUSEADDR – 之前打开的套接字会发生什么?

在unixnetworking编程中,我总是在服务器使用的套接字上设置SO_REUSEADDR选项来监听连接。 这基本上说,另一个套接字可以在机器上的同一个端口上打开。 当从崩溃中恢复并且套接字未正确closures时,这非常有用 – 应用程序可以重新启动,只需在同一个端口上打开另一个套接字并继续监听。

我的问题是,旧sockets会发生什么? 毫无疑问,所有的数据/连接仍然会在旧套接字上被接收。 它是否被操作系统自动closures?

是的,当旧进程结束时,操作系统会自动closures前一个套接字。 你不能正常听同一个端口的原因是套接字虽然是closures的,但在一段时间内(通常是几分钟)仍然处于2MSL状态。 当超时到期时,操作系统会自动将旧套接字从此状态转换出来。

当使用它的程序死亡时,套接字被认为是closures的。 操作系统会处理这么多操作,操作系统将拒绝接受任何进一步的通信。 但是,如果套接字意外closures,另一端的计算机可能不知道对话结束,并且可能仍在尝试进行通信。

这就是为什么在TCP规范中devise了一个相同的端口号可以重新使用之前的等待期。 因为从理论上讲,尽pipe不太可能,但是旧对话中的数据包可能有适当的IP地址,端口号和序号到达,使得接收服务器误将其错误地插入到错误的TCPstream中。

SO_REUSEADDR选项会覆盖该行为,允许您立即重新使用该端口。 实际上,你的意思是说:“我了解风险,并且愿意使用这个港口。”