【问题标题】:Stop spawned process from inherting bound port从继承绑定端口停止生成的进程
【发布时间】:2015-05-23 00:12:45
【问题描述】:

我正在编写一个小型 HTTP 服务器,它会根据请求生成一个 VLC 实例。 但是,如果我停止服务器并尝试在启动的 VLC 实例仍在运行时重新启动它,它会失败并显示error: [Errno 48] Address already in use

服务器:

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        vlcPort = 8191
        linkArg = "example.mp4"
        os.system('~/scripts/backVlcNoBorder.sh --http-port %s %s'%(vlcPort,linkArg))

class ThreadingHTTPServer(ThreadingMixIn, HTTPServer):
    def server_bind(self):
        print "self.allow_reuse_address",self.allow_reuse_address
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.socket.bind(self.server_address)
        # HTTPServer.server_bind(self)

if __name__ == "__main__":
    server = ThreadingHTTPServer(("localhost",1111), Handler)
    server.serve_forever()

它调用的启动 VLC 的脚本 (~/scripts/backVlcNoBorder.sh)

#!/bin/bash
nohup /Applications/VLC.app/Contents/MacOS/VLC $@ >/dev/null 2>/dev/null &

如果我向服务器发出请求,VLC 就会启动。 如果我然后关闭服务器,而不是 VLC,并尝试重新启动服务器,它会失败并显示:

self.allow_reuse_address 1
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
    self.run()
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File "./http_request_server.py", line 263, in serve_on_port
    server = ThreadingHTTPServer(("localhost",1111), Handler)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 420, in __init__
    self.server_bind()
  File "./http_request_server.py", line 256, in server_bind
    self.socket.bind(self.server_address)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 224, in meth
    return getattr(self._sock,name)(*args)
error: [Errno 48] Address already in use

在那之后我跑了lsof -n -i4TCP:1111 | grep LISTEN 看看什么仍然绑定到 1111

bash    24365 admin    3u  IPv4 0x6d73e857a76dcad5      0t0  TCP 127.0.0.1:lmsocialserver (LISTEN)
VLC     24366 admin    3u  IPv4 0x6d73e857a76dcad5      0t0  TCP 127.0.0.1:lmsocialserver (LISTEN)

我不明白为什么 bash 和 VLC 都在听 1111,我猜这可能与 os.system 使用 fork() 有关?

如何在不关闭 VLC 的情况下重新启动服务器,或者如何阻止 VLC 继承绑定的端口?

操作系统是 Mac OSX 10.9

【问题讨论】:

  • 你真的应该使用 subprocess 而不是 os.system
  • @PadraicCunningham 是的,这只是一个最小的例子,并不是真的打算好或太安全。但是使用 subprocess 并没有改变任何实际问题。

标签: python macos bash subprocess port


【解决方案1】:

有两个问题:

  1. 使用subprocess并通过close_fds=True修复第一个;如果不是 http 服务器进程保持 fd 打开
  2. 将您的服务器配置为使用SO_REUSEADDRits analog on your system,如果您重启太快(TIME_WAIT 状态)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 2010-10-07
    • 1970-01-01
    相关资源
    最近更新 更多