I have a simple test application where a TCP/IP server listens for incoming connections, reads the data and closes the connection again and a client which opens connections to the server and sends a package and closes the connection as fast as it can:
The server looks like this:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.setblocking(False) sock.bind(("", 12347)) sock.listen(1) slist = [sock] # use select to poll the sockets while 1: l = select.select(slist, , ) for i in l: conn, addr = i.accept() data = "" while 1: tmp = conn.recv(1024) if not tmp: break data += tmp conn.shutdown(socket.SHUT_RDWR) conn.close()
# Open a connection, send data and close the connection as fast as possible while 1: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(("", 12347)) sock.send("foo") sock.shutdown(socket.SHUT_RDWR) sock.close()
The Problem with this application: After roughly 25.000 Iterations the client quits with a friendly:
error: (99, ‘Cannot assign requested address’)
Netstat shows the problem: roughly 25.000 of these ones:
... tcp 0 0 localhost:56946 localhost:12347 TIME_WAIT tcp 0 0 localhost:47163 localhost:12347 TIME_WAIT tcp 0 0 localhost:42758 localhost:12347 TIME_WAIT ...
I’m not a TCP/IP expert but I thought
SO_REUSEADDR is supposed to address
this problem by allowing to reuse those as-good-as-closed connections in
TIME_WAIT state, or not? So why does it fail in my test application?