Laszlo Nagy <gand...@shopzeus.com> writes: > I have a program that uses socket.bind() and socket.listen() > frequently. After that program stops, it is not able to bind() again for a > while:
This is the usual TIME-WAIT problem. The TCP protocol requires one end of the connection (whichever actually started the close) to keep a record of it for a while after it closes, in order to avoid confusion caused by old packets. > The problem with this, is that this server program SOMETIMES need to be > restarted very quickly. The usual solution is to set the SO_REUSEADDR socket option before binding. This is safe for listening sockets. Here's an interactive session. In [1]: import socket as S In [2]: def make_server_socket(): ...: sk = S.socket(S.AF_INET, S.SOCK_STREAM) ...: sk.bind(('', 12345)) ...: sk.listen(5) ...: return sk ...: In [3]: def serve_client(sk): ...: (nsk, addr) = sk.accept() ...: nsk.send('Hello.\n') ...: nsk.close() ...: In [4]: sk = make_server_socket() In [5]: serve_client(sk) (At this point, I connect to the server in another terminal.) In [6]: sk.close() In [7]: sk = make_server_socket() [...] error: (98, 'Address already in use') And to confirm that it's TIME-WAIT that's stopping us: [ponder ~]netstat -n | grep 12345 tcp 0 0 127.0.0.1:12345 127.0.0.1:49988 TIME_WAIT If I change make_server_socket, then everything works fine. In [8]: def make_server_socket(): ...: sk = S.socket(S.AF_INET, S.SOCK_STREAM) ...: sk.setsockopt(S.SOL_SOCKET, S.SO_REUSEADDR, 1) ...: sk.bind(('', 12345)) ...: sk.listen(5) ...: return sk ...: In [10]: sk = make_server_socket() In [11]: serve_client(sk) In [13]: sk.close() In [14]: sk = make_server_socket() Done. If you try this, note that both the old, closed socket /and/ the new one must have SO_REUSEADDR set on them. If you try this interactively, you'll have to wait for the non-SO_REUSEADDR socket to leave TIME-WAIT before you can bind. But once you've done that, it'll work fine from then on. -- [mdw] -- http://mail.python.org/mailman/listinfo/python-list