How to reuse TCP listening socket immediately after it was connected at least once?

Roy Smith roy at panix.com
Sun May 24 09:21:48 EDT 2009


In article <gvb8fn$7gm$1 at lust.ihug.co.nz>,
 Lawrence D'Oliveiro <ldo at geek-central.gen.new_zealand> wrote:

> In message <mailman.651.1243154739.8015.python-list at python.org>, Igor Katson 
> wrote:
> 
> > I have written a socket server and some arbitrary clients. When I
> > shutdown the server, and do socket.close(), I cannot immediately start
> > it again cause it has some open sockets in TIME_WAIT state. It throws
> > address already in use exception at me.
> 
> There's a reason for that. It's to ensure that there are no leftover packets 
> floating around the Internet somewhere, that you might mistakenly receive 
> and think they were part of a new connection, when they were in fact part of 
> an old one.

In theory, that is indeed the reason for the TIME_WAIT state.  In practice, 
however, using SO_REUSEADDR is pretty safe, and common practice.

You've got several things working in your favor.  First, late-delivery of 
packets is pretty rare.  Second, if some late packet were to arrive, the 
chances of them having the same local and remote port numbers as an 
existing connection is slim.  And, finally, the TCP sequence number won't 
line up.

One thing to be aware of is that SO_REUSEADDR isn't 100% portable.  There 
are some systems (ISTR HP-UX) which use SO_REUSEPORT instead of 
SO_REUSEADDR.  The original specifications weren't very clear, and some 
implementers read them in strange ways.  Some of that old code continues in 
use today.  I only mention this because if you try SO_REUSEADDR and it's 
not doing what you expect, it's worth trying SO_REUSEPORT (or both) to see 
what happens on your particular system.

> The right thing to do is try to ensure that all your connections are 
> properly closed at shutdown. That may not be enough (if your server crashes 
> due to bugs), so the other thing you need to do is retry the socket open, 
> say, at 30-second intervals, until it succeeds.

That may be a reasonable thing to do for production code, but when you're 
building and debugging a server, it's a real pain to not be able to restart 
it quickly whenever you want (or need) to.



More information about the Python-list mailing list