How to tell when a socket is closed on the other end?
Josiah Carlson
josiah.carlson at sbcglobal.net
Wed Jul 25 10:59:09 EDT 2007
Roy Smith wrote:
> In article <1185371863.622473.205010 at 19g2000hsx.googlegroups.com>,
> billiejoex <gnewsg at gmail.com> wrote:
>
>> Hi there.
>> I'm setting up test suite for a project of mine.
>> >From test suite, acting as a client, I'd like to know, in certain
>> situations, if the socket is closed on the other end or not.
>> I noticed that I can "detect" such state if a call to socket.read()
>> returns 0 but it seems a little poor to me. :-\
>> Is there a reliable way to test such socket 'state'?
>
> This isn't really a Python question, it's a Berkeley Socket API question.
> You don't say, but I assume you're talking about a TCP (i.e. SOCKSTREAM)
> connection?
>
> The answer is you can use the select() system call to detect "exceptional
> conditions" on a socket. Python's select module provides this
> functionality, but to understand how to use it, you need to study the
> underlying API.
>
> On the other hand, socket.read() returning 0 works too. What do you find
> "poor" about that? What do you want to know about the connection being
> closed that you don't find out by getting 0 back from read()?
Sockets don't have a read method unless you have used makefile() or have
made them into ssl sockets. They don't return 0, they return empty
strings. If they have a timeout, or the reads were somehow interrupted,
they can return empty strings without the other end having closed the
connection.
There are 3 methods of determining if the remote machine has
closed/shutdown a socket. You offer one, select.select([], [], [sock],
timeout) . The others are to pass that same socket to check whether one
can read or write to the socket. If a socket is readable by select, yet
a recv() produces zero bytes, then the other end has at least signaled
that it is no longer sending (they have performed shutdown(1) or
close()). If a socket is writable by select, yet doesn't accept any
bytes in send(), then the other end has at least signaled that it is no
longer receiving (they have performed shutdown(0) or close()).
In many cases, people only care if *both* directions are open, which is
why asyncore closes the connection if a send or receive do not produce
or consume bytes.
- Josiah
More information about the Python-list
mailing list