How to tell when a socket is closed on the other end?

Roy Smith roy at panix.com
Fri Jul 27 00:40:11 EDT 2007


Jay Loden <python at jayloden.com> wrote:

> The goal of this 
> portion of the test suite we are writing for the project is to determine if a 
> remote server is behaving properly by closing a socket from the server side 
> based on a client-side command.
> 
> Really what's needed is a way to make sure the socket gets closed, and 
> preferably determine if it was closed from the remote end as expected.

This really is way out of scope for a Python newsgroup, but what the heck.  
There is no way to tell through the Socket API *why* the connection was 
shut down, because this information isn't transmitted by the TCP protocol.  
All you know is that the connection did indeed get shut down.  

It could be because the user code at the remote end called close().  Or, it 
could be because the process exited (normally or abnormally) and the kernel 
closed the connection as part of the cleanup.  All the TCP stack at this 
end knows is it got a packet with the FIN bit set.

If you really want to know if the other end completed normally, you need to 
design your user-level protocol to include some "end of session" 
indication.  For example:

> bash-3.2$ telnet mx.panix.com smtp
> Trying 166.84.1.72...
> Connected to mx.panix.com.
> Escape character is '^]'.
> 220 mail1.panix.com ESMTP Postfix
> helo foo
> 250 mail1.panix.com
> quit
> 221 Bye
> Connection closed by foreign host.

The SMTP user-level protocol sent "221 Bye", then, my telnet client saw the 
actual TCP connection close, and printed the "Connection closed by foreign 
host" message.  I know the remote end closed down the connection normally 
because I saw the "221" message in response to my "quit" command.

> Do you 
> know if this is possible to determine from the client side 
> reliably/accurately? Would select()'s exceptional condition flag actually 
> indicate whether or not the root cause of the condition was a socket closed 
> by the remote peer? I've read through the select's manpage and I can't seem 
> to find a reference that indicates what the possible values are for the I/O 
> descriptor sets returned by select. Is there another man page, or a place in 
> the header file for select I can look?

You need to read up about how TCP/IP works.  A good place to start might be 
the Wikipedia article on "Transmission Control Protocol".  The canonical 
textbook on the subject would be:

Richard Stevens
UNIX Network Programming, Volume 1, Second Edition:
Networking APIs: Sockets and XTI
Prentice Hall
1998
ISBN 0-13-490012-X



More information about the Python-list mailing list