SO_REUSEADDR
Dear Lazyweb,
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[0]:
conn, addr = i.accept()
data = ""
while 1:
tmp = conn.recv(1024)
if not tmp:
break
data += tmp
conn.shutdown(socket.SHUT_RDWR)
conn.close()
The Client:
# 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?