471,325 Members | 1,618 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,325 software developers and data experts.

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

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'?

Jul 25 '07 #1
6 14908
In article <11**********************@19g2000hsx.googlegroups. com>,
billiejoex <gn****@gmail.comwrote:
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()?
Jul 25 '07 #2
Roy Smith wrote:
In article <11**********************@19g2000hsx.googlegroups. com>,
billiejoex <gn****@gmail.comwrote:
>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
Jul 25 '07 #3
On 25 Lug, 16:37, Roy Smith <r...@panix.comwrote:
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?
Yes.
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()?
'poor' because it's 'tricky', since that send/write() and recv/read()
should be used for other tasks...
As far as I can tell this works on Linux and Windows, but I don't know
on other platforms.

Jul 25 '07 #4
Roy Smith wrote:
In article <11**********************@19g2000hsx.googlegroups. com>,
billiejoex <gn****@gmail.comwrote:
>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.
Thanks for the interesting information and suggestion of using select(). You are correct that this is actually mostly a socket API question but pertains to Python since the code is all Python's socket and asyncore modules. It might help to step back and explain the original problem. 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. 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?

Thanks for your help,

-Jay
Jul 26 '07 #5
Jay Loden wrote:
Roy Smith wrote:
>In article <11**********************@19g2000hsx.googlegroups. com>,
billiejoex <gn****@gmail.comwrote:
>>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.

Thanks for the interesting information and suggestion of using select(). You are correct that this is actually mostly a socket API question but pertains to Python since the code is all Python's socket and asyncore modules. It might help to step back and explain the original problem. 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. 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?
Use select to determine if the socket is readable and writable. If it
is, yet you can't send or receive to/from it, then it is closed.

- Josiah
Jul 27 '07 #6
Jay Loden <py****@jayloden.comwrote:
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
Jul 27 '07 #7

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by rooster575 | last post: by
1 post views Thread by Mr. Beck | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.