still don't have a title

SO_REUSEADDR

Written on 2009-07-22.

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?

This entry was tagged lazyweb and python