Re: detecting dropped client socket connections

Rajpaul Bagga (rajpaul@hp866a.lanl.gov)
Wed, 6 Jan 1999 10:26:21 -0700 (MST)


Radovan,
Thank for the effort. However, this doesn't help much. When using the
root TSocket::Recv method, a segmentation fault occurs when issued on a
broken pipe, rather than just getting an error code. However, if the
server first tries to send a message down the broken pipe, two things
happen (or rather don't happen).

First, it causes the subsequent Recv() method to NOT cause a seg. fault,
rather it reports this error:

SysError in <UnixRecv>: recv (Broken pipe)
Error in <TUnixSystem::RecvRaw>: cannot receive buffer

But then it unfortunately returns the same -1 code as if it had received
no message (recall I am using non-blocking i/o). This means I can't tell
whether the pipe is closed or just empty.

Secondly, and on a different note, when sending a message down a broken
pipe, the Send() method does not return an error code and doesn't raise a
SIGPIPE as one might think from that same Unix Socket FAQ.

Again, thanks for replying.
-Rajpaul

------------------------------------------------------------------
Rajpaul Bagga email: rajpaul@hp866a.lanl.gov
P-25, M.S. H846 phone: (505) 665-8568
Los Alamos National Laboratory
Los Alamos, NM 87545

On Wed, 6 Jan 1999, Radovan CHYTRACEK wrote:

> UNIX sockets programming FAQ says the following:
>
> 2.1 How can I tell when a socket is closed on the other end?
>
> >From Andrew Gierth ( andrewg@microlise.co.uk):
>
> AFAIK:
>
> If the peer calls close() or exits, without having messed with SO_LINGER, then
> our calls to read() should return 0. It is less clear
> what happens to write() calls in this case; I would expect EPIPE, not on the
> next call, but the one after.
>
> If the peer reboots, or sets l_onoff = 1, l_linger = 0 and then closes, then
> we should get ECONNRESET (eventually) from
> read(), or EPIPE from write().
>
> I should also point out that when write() returns EPIPE, it also raises the
> SIGPIPE signal - you never see the EPIPE error unless
> you handle or ignore the signal.
>
> If the peer remains unreachable, we should get some other error.
>
> I don't think that write() can legitimately return 0. read() should return 0
> on receipt of a FIN from the peer, and on all following
> calls.
>
> So yes, you must expect read() to return 0.
>
> As an example, suppose you are receiving a file down a TCP link; you might
> handle the return from read() like this:
>
> rc = read(sock,buf,sizeof(buf));
> if (rc > 0)
> {
> write(file,buf,rc);
> /* error checking on file omitted */
> }
> else if (rc == 0)
> {
> close(file);
> close(sock);
> /* file received successfully */
> }
> else /* rc < 0 */
> {
> /* close file and delete it, since data is not complete
> report error, or whatever */
> }
>
>
> Hope this helps
>
> Radovan
>
> Rajpaul Bagga wrote:
> >
> > Hello all.
> > I'm trying to develop a network server/client setup where the server
> > periodically checks for messages from the client. The socket is set for
> > non-blockin i/o so that when it tries to receive a message if nothing is
> > there it can go on to do other things.
> >
> > The problem occurs when the client drops the connection. I need to assume
> > that it will not always send a nice message requesting to drop the
> > connection. After the client has dropped a connection, if I issues a
> > socket->Recv() command, I get a SIGSEGV signal. Is there someway to
> > detect whether the client has dropped the connection before trying to
> > receive a message?
> >
> > Thanks,
> > -Rajpaul
> >
> > ------------------------------------------------------------------
> > Rajpaul Bagga email: rajpaul@hp866a.lanl.gov
> > P-25, M.S. H846 phone: (505) 665-8568
> > Los Alamos National Laboratory
> > Los Alamos, NM 87545
>
> --
> Radovan Chytracek
> LHCb experiment at CERN
> Radovan.Chytracek@cern.ch
> http://wwwinfo.cern.ch/~chytrace
>