Linux上的TIME_WAIT和EADDRINUSE

时间:2017-05-08 10:08:21

标签: linux time-wait

我有一个系统,其中在后台运行的服务器进程由控制程序控制。

控制程序是一个简单的脚本,它执行一个命令然后退出。对于Run命令,它创建一个新的服务器进程;对于其他人(包括Shutdown),它通过保留的控制端口将命令发送到服务器。

控制程序创建一个套接字,连接到服务器的控制端口,发送一个字符的数据(一个命令),从套接字读取回复,关闭套接字,显示对用户的回复并退出。服务器接受控制套接字上的连接,读取数据字符,发送回复,关闭子套接字并继续监听。当服务器关闭时,它也会关闭父控件套接字。

多年来,它一直在Windows XP / Python 2.6.6上运行。最近我们尝试移植到Linux(Ubuntu 16.04.2 GNU / Linux 4.4.0-62-generic x86_64 / Python 2.7.12),但是有重启命令(Shutdown紧接着Run后)失败:当新服务器进程尝试时要将控制套接字绑定到控制端口,它将获得EADDRINUSE。

netstat的输出显示用于Shutdown命令的连接仍处于TIME_WAIT状态,并持续约两分钟。

我已经回顾了此主题的先前帖子。我已经尝试在服务器的控制套接字上设置SO_REUSEADDR和/或SO_REUSEPORT。我已经尝试增强服务器和控制程序之间的协议,以确保控制程序首先关闭其连接的一面,但到目前为止,我还没有找到一个有效的组合。我想知道是否有任何解决方案。

鉴于服务器和控制程序都在同一台机器上运行,连接两端的详细信息将在操作系统的状态表中,并且必须在TIME_WAIT中保留一个或另一个。

控制程序的条目是否阻止服务器绑定到端口?

我注意到在Windows上,连接仍处于TIME_WAIT状态,但在Windows上不会阻止新服务器进程绑定到同一个控制端口。

1 个答案:

答案 0 :(得分:0)

我已经回答了我自己的问题。为了获得所需的行为,我需要在服务器的控制套接字(仅限)上设置SO_REUSEADDR(仅限)。没有必要使用SO_REUSEPORT。没有必要对控制程序做任何事情。首先关闭连接的方法没有区别。

我的第一次尝试没有奏效,因为我犯了一个愚蠢的错误。 (我使用了错误的变量。)