SPUG: Closing HTTP::Daemon port

Ben Reser ben at reser.org
Wed Aug 13 22:54:09 CDT 2003


On Mon, Aug 11, 2003 at 10:46:15PM -0700, Marc M. Adkins wrote:
> OK, here's a stripped-down version.  It demonstrates the behavior on
> Mandrake 9.1.
> 
> Create two terminals.  Run testsvr.pl in one.  Wait until it says "Server
> Created."  Run testsvr.pl in the other.  It should shut down the first one
> and run in the second one.  Repeat as necessary.  Fun, huh?
> 
> On Windows this happens immediately (more or less).  On Linux it takes 55-60
> seconds.  There's a counter in the code to keep you company.
> 
> Since my last post I opened up LWP::Simple and swiped the 'trivial' function
> for testing purposes.  Didn't change the behavior.  While it was in I did
> notice that there was a 60 second timeout on the connection to the server
> for the /quit command.  I changed this to 30 seconds and it didn't affect
> anything.  So I removed that code and went back to LWP::Simple.
> 
> I previously said that the behavior didn't happen if I used <ctrl-C> to
> interrupt the original server.  That is not in fact the case (or at least I
> can't duplicate that feature now).  If I <ctrl-C> the first server and
> _then_ start the second it _still_ takes almost a minute.
> 
> The sleep 1 at the top of the wait loop is necessary on Windows but not on
> Linux.  It doesn't affect the behavor on Linux, it just isn't necessary.

Add ReuseAddr => 1 to your call to new for HTTP::Daemon.  

Found by gooling for: linux HTTP::Daemon TIME_WAIT
http://cookbook.soaplite.com/#reusing%20sockets%20on%20restart

The document mentions Reuse which according to the IO::Socket::INET pod
is deprecated in favor of ReuseAddr.  

Windows apparently allows you to reuse sockets immediately.  Linux (and
UNIX implementations in general) places the port in the status of
TIME_WAIT on the idea that there might still be data floating around out
there on the network from the existing connections.  If a server was
allowed to bind to the same address and port it might receive partial
data with the same proto, local addr, local port, remote addr and remote
port that would "corrupt" an existing connection.  You can find an
explanation of the possible error conditions that TIME_WAIT is intended
to avoid here:
http://www.unixguide.net/network/socketfaq/2.7.shtml

ReuseAddr sets SO_REUSEADDR on your bind which tells the socket
implementation that while you realize you may get bizzare results but
that you don't want to wait.  Even though the error conditions above
mentioned are possible they are highly improbable an explanation of why
can be found here:
http://www.unixguide.net/network/socketfaq/4.5.shtml

HTHs

-- 
Ben Reser <ben at reser.org>
http://ben.reser.org

"What upsets me is not that you lied to me, but that from now on I can
no longer believe you." -- Nietzsche



More information about the spug-list mailing list