Re: detecting dropped client socket connections

From: Fons Rademakers (Fons.Rademakers@cern.ch)
Date: Thu Jan 14 1999 - 13:59:49 MET


Hi Rajpaul,

   just to tell you that I've improved the error handling of the TSocket
class in the new development version of ROOT (which should be publicly
available soon).

In the new version TSocket::Recv() returns either:

 0   -- peer has closed connection (SIGSEGV problem fixed)
-1   -- general error
-4   -- EWOULDBLOCK in case socket is in non-blocking mode and nothing to read

and TSocket::Send() returns:

-1   -- in case pipe is closed SIGPIPE signal is handled and -1 returned

Cheers, Fons.




Rajpaul Bagga wrote:
> 
> 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
> >

-- 
Org:    CERN, European Laboratory for Particle Physics.
Mail:   1211 Geneve 23, Switzerland          Phone: +41 22 7679248
E-Mail: Fons.Rademakers@cern.ch              Fax:   +41 22 7677910



This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:28 MET