Here is my code to run the server:
class MyRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
#....
PORT = 8089
httpd = SocketServer.TCPServer(("", PORT), MyRequestHandler)
httpd.allow_reuse_address = True
print "Serving forever at port", PORT
try:
httpd.serve_forever()
except:
print "Closing the server."
httpd.server_close()
raise
Yet this is what happens:
^CClosing the server.
Traceback (most recent call last):
File "server.py", line 118, in <module>
self.send_error(400, "Unimplemented GET command: %s" % (self.path,))
File "/home/claudiu/local/lib/python2.6/SocketServer.py", line 224, in serve_forever
r, w, e = select.select([self], [], [], poll_interval)
KeyboardInterrupt
(.virtualenv)claudiu@xxx:~/xxx$ python server.py
Traceback (most recent call last):
File "server.py", line 122, in <module>
httpd = SocketServer.TCPServer(("", PORT), MyRequestHandler)
File "/home/claudiu/local/lib/python2.6/SocketServer.py", line 402, in __init__
self.server_bind()
File "/home/claudiu/local/lib/python2.6/SocketServer.py", line 413, in server_bind
self.socket.bind(self.server_address)
File "<string>", line 1, in bind
socket.error: [Errno 98] Address already in use
Why? I close the server and set allow_reuse_address
to True... Using python 2.6.8.
The
[Err 98] Address already in use
is due to the fact the socket was.close()
but it's still waiting for enough time to pass to be sure the remote TCP received the acknowledgment of its connection termination request (see TIME_WAIT). By default you are not allowed to bind a socket if there a socket bound to that port but you can override that withallow_reuse_address
(SO_REUSEADDR)Although is possible to mutate
TCPServer.allow_reuse_addr
(as proposed in this other answer), I think is more clean to your own subclass ofTCPServer
whereallow_reuse_address
is set toTrue
:You can use definitely set
allow_reuse_address
on the instance itself (without messing with classes) but you need to useTCPServer(..., bind_and_activate=False)
, otherwise the socket will be bound before you have a chance to change theallow_reuse_address
setting. Then you need to manually call.server_bind()
and.server_activate()
beforeserve_forever()
:Thanks to the other answers, I figured it out.
allow_reuse_address
should be on the class, not on the instance:I'm still not sure why closing the socket didn't free it up for the next run of the server, though.
It is because you have to set SO_REUSEADDRESS before you bind the socket. As you are creating and binding the socket all in one step and then setting it, it is already too late.
It is because TCP TIME_WAIT.
Somebody discovered this exact problem.