2017-05-08 60 views
0

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

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

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

这一直工作在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的输出显示,用于关断命令的连接保持在TIME_WAIT状态,并且继续如此大约两分钟。

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

由于在同一台机器上运行的服务器和控制程序,连接两侧的细节将在操作系统的状态表,以及一个或其它必须在TIME_WAIT留下。

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

我注意到,在Windows上还连接在TIME_WAIT状态下离开,但在Windows并不妨碍新的服务器进程捆绑到同一个控制端口。

+0

嗨,欢迎来到StackOverflow!您可能想编辑您的问题以包含一些格式。现在,它很难阅读! –

回答

0

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

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