next up previous Back to Operating Systems Home Page
Next: Assig 4 - Key Up: 1997 term messages Previous: Assig. 4 - Verbose

Sockets bound, stuck and such

Straight from the graveyard On Sun, 6 Apr 1997, Zombie...|> wrote:

> I'm in a bit of a 'bind' you could say...
> Is there any way to 'unbind' a socket??

Yeah, close(2) it ;-)

> I was trying to play around with the socket and bind calls to see how they
> work, and I'm not sure what I did, because it worked when I first used
> the bind call, but now when I try to run my program I keep getting a bind
> error--that the address is already in use...and so now I can't do
> anything with it.

This is a different problem altogether. The short answer is 
        "No, you may not re-use the port for the first 60 seconds
         after a bound socket is closed (explicitly or because
         the program exited".

The timeout is a system configuration parameter, 60 seconds is a typical
value.

So if you want to restart immediately, just use a different port (maybe
passing it from the command line).

Why - long answer.
==================

If you run netstat(8), and look for the status of your port right after
exiting, you'll see it reported as "XXX_WAIT", where XXX is one of "TIME",
"FIN", "CLOSE". This means that the kernel has succesfully closed your
socket but, for various reasons, is still completing its removal from the
TCP/IP kernel tables. 

The "deep" reason is for this is that *both* the communicating partners
must rendez-vous for a connection shutdown, exactly as they do when
opening the connection: TCP/IP exchanges appropriate packets to inform
both partners that the connection is going away. 

More precisely, the possible status of a socket upon a connection shutdown
is one of the following (as reported by netstat(8)).

       FIN_WAIT1
              The socket is closed, and the connection  is  shut-
              ting down.
       FIN_WAIT2
              Connection is closed, and the socket is waiting for
              a shutdown from the remote end.
       TIME_WAIT
              The socket is waiting after close for remote  shut-
              down retransmission.
       CLOSE_WAIT
              The  remote  end  has  shut  down,  waiting for the
              socket to close.

The most common case (probably the one you are seeing) is TIME_WAIT. It 
happens like this:

1) the server closes the socket accidentally; 

2) the kernel (tcp/ip) on the server side puts the port in FIN_WAIT1 state,  
   informs the kernel (tcp/ip) on the client side, then puts the port in
   FIN_WAIT2 state, waiting for a confirmation;

3) A confirmation would be sent if, at this point, the client closed its
   own socket. But the client is really waiting for something else (a "good" 
   message from the server), and thus dies trying to read from
   the socket (getting SIGPIPE);  

4) the kernel on the server side puts the port in TIME_WAIT state, waits 
   for a while (usually 60 seconds)  hoping to receive a shutdown 
   confirmation from the client, then finally  kills the connection on 
   its own account. 

Only now can the port be bound again. 

Notice that the problem really exists only for the "listening" socket of a
server (a.k.a. the "well known port" whcih clients connect to). All other
ports bound by connect(2) and accept(2) are randomly chosen by the kernel
on both sides, so there'll be always free ones (the kernel has 16 bits
of port number to fish from).

Ciao
Franco



\ Franco Callari