我有一个系统,其中在后台运行的服务器进程由控制程序控制。
控制程序是一个简单的脚本,它执行一个命令然后退出。对于 Run 命令,它会创建一个新的服务器进程;对于其他人(包括关机),它通过保留的控制端口将命令发送到服务器。
控制程序创建一个套接字,连接到服务器的控制端口,发送一个字符的数据(一个命令),从套接字读取答复,关闭套接字,向用户显示答复并退出。服务器接受控制套接字上的连接,读取数据字符,发送回复,关闭子套接字并继续侦听。当服务器关闭时,它也会关闭父控制套接字。
这已经在 Windows XP / Python 2.6.6 上运行了很多年。最近我们尝试移植到 Linux(Ubuntu 16.04.2 GNU/Linux 4.4.0-62-generic x86_64 / Python 2.7.12),但是重启命令(立即关机后运行)失败:当新的服务器进程尝试要将控制套接字绑定到控制端口,它会获取 EADDRINUSE。
netstat 的输出显示用于 Shutdown 命令的连接保持在 TIME_WAIT 状态,并持续了大约两分钟。
我已经查看了有关此主题的先前帖子。我尝试在服务器的控制套接字上设置 SO_REUSEADDR 和/或 SO_REUSEPORT。我已经尝试增强服务器和控制程序之间的协议,以确保控制程序首先关闭它的连接端,但到目前为止我还没有找到有效的组合。我想知道是否有任何解决方案。
鉴于服务器和控制程序都运行在同一台机器上,连接双方的详细信息将在操作系统的状态表中,并且必须在 TIME_WAIT 中保留一个或另一个。
控制程序的条目是否会阻止服务器绑定到端口?
我注意到在 Windows 上也有一个连接处于 TIME_WAIT 状态,但在 Windows 上不会阻止新的服务器进程绑定到同一个控制端口。