我有一个在后台运行的服务器进程由控制程序控制的系统。
控制程序是一个简单的脚本,它执行一个命令,然后退出。对于Run命令,它创建一个新的服务器进程;对于其他进程(包括关闭),它通过保留的控制端口将命令发送到服务器。
控制程序创建一个套接字,连接到服务器的控制端口,发送一个字符的数据(一个命令),从套接字中读取回复,关闭套接字,向用户显示回复并退出。服务器接受控制套接字上的连接,读取数据字符,发送应答,关闭子套接字并继续侦听。当服务器关闭时,它也会关闭父控件套接字。
多年来,它一直在Windows XP/Python 2.6.6上运行。最近我们尝试了移植到Linux(Ubuntu16.04.2GNU/Linux4.4.0-62-genericx86x64/Python2.7.12),但是Restart命令(Shutdown紧接着Run)失败了:当新的服务器进程试图将控制套接字绑定到控制端口时,它得到了EADDRINUSE。
netstat的输出显示,用于Shutdown命令的连接仍处于TIME_WAIT状态,并持续大约两分钟。
我已经复习了以前关于这个主题的文章。我尝试在服务器的控制套接字上设置sou REUSEADDR和/或sou REUSEPORT。我尝试过增强服务器和控制程序之间的协议,以确保控制程序首先关闭其连接的一端,但到目前为止,我还没有找到一个有效的组合。我想知道是否有什么解决办法。
如果服务器和控制程序都在同一台计算机上运行,则连接双方的详细信息都将显示在操作系统的状态表中,其中一方必须等待时间。
控制程序的条目是否阻止服务器绑定到端口?
我注意到,在Windows上,还有一个连接处于TIME_WAIT状态,但在Windows上,它不阻止新服务器进程绑定到同一个控制端口。
最佳答案
我已经回答了我自己的问题。要获得所需的行为,我需要在服务器的控制套接字(仅)上设置sou REUSEADDR(仅)。不必使用sou REUSEPORT。不必对控制程序做任何事。哪一侧先关闭连接没有区别。
我的第一次尝试没有成功,因为我犯了一个愚蠢的错误。(我使用了错误的变量。)
关于linux - 在Linux上的TIME_WAIT和EADDRINUSE,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43844917/