2009-04-22 49 views
27

在unix网络编程中,我总是在服务器使用的套接字上设置SO_REUSEADDR选项来监听连接。这基本上说,另一个套接字可以在机器的同一端口上打开。当从崩溃中恢复并且套接字没有被正确关闭时,这非常有用 - 应用程序可以重新启动,并且只需在同一端口上打开另一个套接字并继续监听。使用SO_REUSEADDR - 先前打开的套接字会发生什么?

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

+1

澄清:程序崩溃后,操作系统例如Linux Kernel,将自动关闭套接字。有协议原因(TCP)为什么你不想立即重新打开连接。 – unixman83 2012-01-29 08:39:53

+2

关于这个主题必须阅读:http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-implications-implications-for-protocols-and-scalable-servers.html – 2012-04-03 08:57:15

回答

24

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

29

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

这就是为什么在TCP规范中设计了一个等待期,然后才能重用相同的端口号。因为从理论上讲,尽管不太可能,但是旧会话中的数据包可能会有适当的IP地址,端口号和序列号到达,这样接收服务器就会错误地将它插入到错误的TCP流中。

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

相关问题