Checking for a closed socket connection

Checking for a closed socket connection

Post by jalva.. » Thu, 25 Jan 1996 04:00:00



Is there a simple way to test a socket descriptor for a closed
connection (e.g. if the connection to the other side was lost
and is no longer valid) ?

Thanks,
--Jesus Alvarez

 
 
 

Checking for a closed socket connection

Post by Robert Kl » Fri, 26 Jan 1996 04:00:00



 >Is there a simple way to test a socket descriptor for a closed
 >connection (e.g. if the connection to the other side was lost
 >and is no longer valid) ?

read() to/write() from it and see if the function returns a -1 :)

                                                                robert

 
 
 

Checking for a closed socket connection

Post by Vic Metcal » Fri, 26 Jan 1996 04:00:00


: Is there a simple way to test a socket descriptor for a closed
: connection (e.g. if the connection to the other side was lost
: and is no longer valid) ?

Though I've heard that read() and write() should return -1 in this condition,
it is my experience with linux that read() and write() return 0.  I have had
some success with checking for a return of <= 0.  If I persist in my reads
and writes, I eventually get an EPIPE error with a -1 return.

According to previous posts I have read, this is valid.  Some other systems
will return ECONNRESET, or EINVAL in errno.

Is checking for the 0 return from read()/write() a bad idea?  Can this happen
under normal conditions?

BTW, questions of this sort are usually dealt with in comp.unix.programmer,
since the answer should be generic across unix platforms.  I have added
comp.unix.programmer to the cross-post list, and directed all followups to
comp.unix.programmer alone.  I am working on a unix-socket-faq for that
newsgroup which I hope to post on the weekend.  

The above answer by the way is taken word for word from the faq.  Please
post a follow-up if you see an error in it.

Thanks,
  Vic.

 
 
 

Checking for a closed socket connection

Post by Arnt Gulbrandse » Sat, 27 Jan 1996 04:00:00




>  >Is there a simple way to test a socket descriptor for a closed
>  >connection (e.g. if the connection to the other side was lost
>  >and is no longer valid) ?

> read() to/write() from it and see if the function returns a -1 :)

write() is unfortunate, of course.  read() is better, unless your
application can't store any read data until it _really_ wants to read.

But you do have the option of using getpeername(), which should work
nicely.

--Arnt

 
 
 

Checking for a closed socket connection

Post by Pierre-Yves Kerembell » Sat, 27 Jan 1996 04:00:00




> >Is there a simple way to test a socket descriptor for a closed
> >connection (e.g. if the connection to the other side was lost
> >and is no longer valid) ?
>read() to/write() from it and see if the function returns a -1 :)

You can also use a "setsockopt" system-call and set the
 SO_KEEPALIVE flag for that particular socket : your process
will receive a SIGPIPE if the peer hangs up
(of course, it's your duty to handle that signal properly)
By the way, the "read" system-call won't return -1 in any case (trust me !)
A more secure code would be something like that :

   ...
   status = select(...)
   if (status>0)
   {
      size = read(...);
      if (size<=0) return(SOCKET_DOWN);
   }
   ...
(note the '<=' and not just '<')

Pierre-Yves

 
 
 

Checking for a closed socket connection

Post by Bill Richte » Sun, 28 Jan 1996 04:00:00


Bear in mind, depending on how you set *timeout in
select, a return from select of 0 merely indicates
the timer expired with nothing read from the socket
or in polling mode, nothing ready.  Yet the socket
can be connected to a peer.

You could if size <= 0 then do a read() or getpeername()
Which would set errno and return a -1.
Catching SIGPIPE is good too, but takes a bit longer
to get the signal, depending on the state of your
process.

Quote:> A more secure code would be something like that :

>    ...
>    status = select(...)
>    if (status>0)
>    {
>       size = read(...);
>       if (size<=0) return(SOCKET_DOWN);
>    }
>    ...
> (note the '<=' and not just '<')

> Pierre-Yves

 
 
 

Checking for a closed socket connection

Post by Simon J Mu » Mon, 29 Jan 1996 04:00:00




>  >Is there a simple way to test a socket descriptor for a closed
>  >connection (e.g. if the connection to the other side was lost
>  >and is no longer valid) ?
> read() to/write() from it and see if the function returns a -1 :)

is it acceptable therefore to read 0 bytes, or write 0 bytes?
we have an application which uses a "ping" type protocol to determine if the remote machien
is still connected, and this maybe for us a useful way of determining the connection is
still valid at the remote end?

Are there better ways to do this?

regards

Simon Mudd

 
 
 

Checking for a closed socket connection

Post by Robert Kl » Tue, 30 Jan 1996 04:00:00




 >> read() to/write() from it and see if the function returns a -1 :)
 >is it acceptable therefore to read 0 bytes, or write 0 bytes?

I read an old doc about read() last week, and it seems that it's very
OS-dependent what read() will return in certain cases. My guess is that
checking for 0-or-lower as return-value is best to check a 'hang-up' of
the remote server.

                                                                robert

 
 
 

Checking for a closed socket connection

Post by Arnt Gulbrandse » Tue, 30 Jan 1996 04:00:00





> >  >Is there a simple way to test a socket descriptor for a closed
> >  >connection (e.g. if the connection to the other side was lost
> >  >and is no longer valid) ?

> > read() to/write() from it and see if the function returns a -1 :)

> is it acceptable therefore to read 0 bytes, or write 0 bytes?

The TCP protocol allows packets with 0 bytes payload, but I would not
recommend using it at the application layer - you're staking too much
on the kernel implementation.

If you need real keepalive, and the two-hour default of
setsockopt(SO_KEEPALIVE) isn't enough, you need to design it into your
protocol.  Anything else is going to break on one TCP stack or
another; there are so many of them, all slightly different.

SMTP has NOOP, which tells the server to send a "250 OK" and do
nothing else.  I recommend that you do something similar.

         NOOP (NOOP)

            This command does not affect any parameters or previously
            entered commands.  It specifies no action other than that
            the receiver send an OK reply.

            This command has no effect on any of the reverse-path
            buffer, the forward-path buffer, or the mail data buffer.

--Arnt

 
 
 

Checking for a closed socket connection

Post by mev.. » Tue, 30 Jan 1996 04:00:00


If a TCP socket is opened as SOCK_STREAM, (the normal case), then the concept of '0 length
packets' doesn't appy at the application layer.  Stream sockets have no concept of packet boundaries,
a send of 0 bytes would be an effective NOP, resulting in no actual network traffic.  That's
why recv is free to return 0 as a unique indicator of stream termination.  Detecting stream
termination during outbound operations in where a lot of implementation defined behavior comes
into play.  A send to a broken stream socket on AIX typically results in ECONNRESET, sometimes
ETIMEDOUT, on OS/2, it's always EPIPE, and so on ...
 
 
 

Checking for a closed socket connection

Post by Rob Janss » Wed, 31 Jan 1996 04:00:00



Quote:>> is it acceptable therefore to read 0 bytes, or write 0 bytes?
>The TCP protocol allows packets with 0 bytes payload, but I would not
>recommend using it at the application layer - you're staking too much
>on the kernel implementation.

TCP cannot send 0-byte packets.  Actually, a user cannot send TCP packets
at all!
TCP is a stream-based protocol.  The user submits data, and TCP is free
to packetize it in packets of any size it likes, and send it on the
connection.  You cannot be sure the packet size will have any relation
to the size of your write().

The only thing you can be quite sure of, is that a 0-size write will not
result in a 0-size packet.  This is because such a packet is merely an
ACK, and would not be acked by the other side.  There is little point
in sending it....
(note that a "keepalive" may look like a 0-size packet, but in fact it
contains an already-acked sequence number, and thus it is not really the
same thing.  the other side sees it as an old duplicate, and ACKs it).

UDP, being packet oriented, can send 0-size packets.  However, this is
tricky just as well, as some broken implementations may not deliver the
received 0-byte packet to the user.
(There was a bug in this in Linux as well, but it was fixed after I hit
it...  the RFC 868 "Time Protocol" specifies that you can send a 0-size
UDP packet to the server, and get the current time in a UDP reply)

Rob
--
+------------------------------------+--------------------------------------+


+------------------------------------+--------------------------------------+

 
 
 

Checking for a closed socket connection

Post by Arnt Gulbrandse » Thu, 01 Feb 1996 04:00:00


Following up to my own posting: I realized just after posting it that
even though some TCP stacks may make is possible for suitably contorte
clients to _write_ 0 bytes, I can't imagine that any legal stacks make
it possible for a client to receive 0 bytes.

Which is good.

--Arnt

 
 
 

Checking for a closed socket connection

Post by Arnt Gulbrandse » Thu, 01 Feb 1996 04:00:00




ites:

> >> is it acceptable therefore to read 0 bytes, or write 0 bytes?

> >The TCP protocol allows packets with 0 bytes payload, but I would not
> >recommend using it at the application layer - you're staking too much
> >on the kernel implementation.

> TCP cannot send 0-byte packets.  Actually, a user cannot send TCP packets
> at all!

True.  And yet the TCP protocol allows the sending TCP stack to send a
packet with 0 bytes payload (without payload, if you wish).  The
crucial difference is that the user cannot send TCP packets at all.

It's possible for a user program to ask, but not to force the TCP
stack to send off a packet.  Before anyone says "that's wrong":
Consider what happens if the TCP stack obliges, the packet sent is
lost, and the client sends more data before the TCP stack resends.

There is a major difference between the TCP protocol and the various
implementations of it, and between the TCP stack and the TCP-using
client program.

Quote:> TCP is a stream-based protocol.  The user submits data, and TCP is free
> to packetize it in packets of any size it likes, and send it on the
> connection.  You cannot be sure the packet size will have any relation
> to the size of your write().

Quite.

As I said, even if inspection shows it to "work" on one particular TCP
stack it probably won't work on many others.

(I know I do it myself, but I really hate it when people followup to a
posting of mine without, apparently, reading it through.)

--Arnt

 
 
 

Checking for a closed socket connection

Post by Borje Jonss » Fri, 02 Feb 1996 04:00:00



says...


>: Is there a simple way to test a socket descriptor for a closed
>: connection (e.g. if the connection to the other side was lost
>: and is no longer valid) ?

>Though I've heard that read() and write() should return -1 in this
condition,
>it is my experience with linux that read() and write() return 0.  I have
had
>some success with checking for a return of <= 0.  If I persist in my
reads
>and writes, I eventually get an EPIPE error with a -1 return.

>According to previous posts I have read, this is valid.  Some other
systems
>will return ECONNRESET, or EINVAL in errno.

>Is checking for the 0 return from read()/write() a bad idea?  Can this
happen
>under normal conditions?

.
.
.

Quote:

>Thanks,
>  Vic.

I recently made a small program that communicate between a Linux and
an AIX box. A server process waits for connect from a client and then
read data from client and write back answers. When the client is forced
to disconnect (typing ctrl-C) the read call on server process returns -1
and errno ECONNRESET or 0 and errno 0 on the AIX box.The same is true
for Linux.
The problem is that there is no apparent way to tell when -1 and
ECONNRESET is returned or when 0 and errno 0 is returned.

regards
Borje Jonsson

 
 
 

1. Checking for a closed socket connection

: Is there a simple way to test a socket descriptor for a closed
: connection (e.g. if the connection to the other side was lost
: and is no longer valid) ?

Though I've heard that read() and write() should return -1 in this condition,
it is my experience with linux that read() and write() return 0.  I have had
some success with checking for a return of <= 0.  If I persist in my reads
and writes, I eventually get an EPIPE error with a -1 return.

According to previous posts I have read, this is valid.  Some other systems
will return ECONNRESET, or EINVAL in errno.

Is checking for the 0 return from read()/write() a bad idea?  Can this happen
under normal conditions?

BTW, questions of this sort are usually dealt with in comp.unix.programmer,
since the answer should be generic across unix platforms.  I have added
comp.unix.programmer to the cross-post list, and directed all followups to
comp.unix.programmer alone.  I am working on a unix-socket-faq for that
newsgroup which I hope to post on the weekend.  

The above answer by the way is taken word for word from the faq.  Please
post a follow-up if you see an error in it.

Thanks,
  Vic.

2. smbclient, apsfilter, printing from linux ->windows

3. Closing sockets and closing connections

4. Doom and sound in Linux: HELP

5. how to check whether a socket is closed?

6. aha1540b and cd-rom drive

7. Checking a closed socket question.

8. SCSI_ABORT_BUSY help please?

9. Check if a socket is closed

10. How to check if a client closed connection?

11. How do I properly close a socket connection?

12. How to detect when socket connection closes?

13. Linux sockets problem (closed connections staying open?)