python xinetd客户端断开处理

时间:2010-07-06 10:05:51

标签: python linux

这可能是也可能不是编码问题。它也可能是一个xinetd deamon问题,我不知道。

我有一个python脚本,它是从运行xinetd的linux服务器触发的。 Xinetd已设置为仅允许一个实例,因为我只希望一台机器能够连接到该服务,因此也受到IP的限制。

目前,当客户端连接到xinetd时,服务正常工作,脚本开始将其输出发送到客户端计算机。但是,当客户端断开连接时(即:由于重新启动),该进程在服务器上仍处于活动状态,这会阻止客户端在完成重新启动后连接等等。

问:如何在python中检测到客户端已断开连接。也许我可以测试客户端是否不再读取stdout(然后退出脚本),或者在客户端断开连接时是否有更多的方法让xinetd中的子进程被终止?

(我在RHEL5 linux上使用python 2.4.3 - 需要2.4的解决方案,但3.1解决方案也很有用。)

3 个答案:

答案 0 :(得分:2)

为SIGHUP添加信号处理程序。 (x)inetd在套接字断开时发送。

答案 1 :(得分:0)

监控发送给您的进程的信号。也许你的脚本没有响应xinet发送的SIGHUP,监控信号并让它死掉。

答案 2 :(得分:0)

你似乎没有获得SIGHUP,但你确实得到了一个SIGPIPE,至少只要你在连接上尝试任何IO。如果应用程序花费很长时间没有执行任何IO,那么您可以启动一个线程读取stdin以确保在断开连接后立即获得SIGPIPE。这对我的应用来说已经足够了,但之后我没有使用xinetd给我的任何管道。

我在网上看到过几个人在谈论SIGHUP在客户端断开时发送的地方,所以我写了一个inetd python脚本来测试几个服务器(一个inetd和另一个xinetd),所以你可以用它来检查发送的信号。它只是将它找到的内容记录到/var/log/test.log。也许它会有用。

#!/usr/bin/python

import os, signal, sys

skip = ["SIGKILL", "SIG_DFL", "SIGSTOP", "SIG_IGN", "SIGCLD", "SIGCHLD"]
name_map = {}
identifiers = [i for i in dir(signal) if i.startswith("SIG") and not i in skip]

for i in identifiers:
    name_map[getattr(signal, i)] = i

def handler(num, frame):
    signame = name_map[num]
    os.system("echo handled %s >> /var/log/test.log" % signame)

if __name__ == "__main__":
    for id, name in name_map.iteritems():
        signal.signal(id, handler)

    while True:
        print sys.stdin.readline()
        sys.stdout.flush()