0

I'm writing a little HTTP server that spawns an VLC instance on request. However if I stop my server and try to restart it while the started VLC instance is still running it fails with error: [Errno 48] Address already in use

The server:

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()

The script it calls to start VLC (~/scripts/backVlcNoBorder.sh)

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

If I make a request to the server, VLC starts. If I then shut down the server, but not VLC, and try to restart the server, it fails with:

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

After that I ran lsof -n -i4TCP:1111 | grep LISTEN to see whats still bound to 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)

I don't unterstand why both bash and VLC are listening to 1111, I guess it has to do with os.system with uses fork() maybe?

How can I restart the server without having to shut down VLC, or how to I stop VLC from inherting the bound port?

OS is Mac OSX 10.9

Pete9119
  • 117
  • 1
  • 2
  • 7

1 Answers1

0

There are two issues:

  1. Use subprocess and pass close_fds=True to fix the first; if some other than http server process keeps the fd open
  2. Configure your server to use SO_REUSEADDR or its analog on your system if you are restarting it too fast (TIME_WAIT state).
Community
  • 1
  • 1
jfs
  • 346,887
  • 152
  • 868
  • 1,518