Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Jan 2013 10:46:05 -0700
From:      Ian Lepore <ian@FreeBSD.org>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        freebsd-hackers <freebsd-hackers@FreeBSD.org>
Subject:   Re: Sockets programming question
Message-ID:  <1359481565.93359.160.camel@revolution.hippie.lan>
In-Reply-To: <20130128160238.GT2522@kib.kiev.ua>
References:  <1359385907.93359.84.camel@revolution.hippie.lan> <20130128160238.GT2522@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 2013-01-28 at 18:02 +0200, Konstantin Belousov wrote:
> On Mon, Jan 28, 2013 at 08:11:47AM -0700, Ian Lepore wrote:
> > I've got a question that isn't exactly freebsd-specific, but
> > implemenation-specific behavior may be involved.
> > 
> > I've got a server process that accepts connections from clients on a
> > PF_LOCAL stream socket.  Multiple clients can be connected at once; a
> > list of them is tracked internally.  The server occasionally sends data
> > to each client.  The time between messages to clients can range
> > literally from milliseconds to months.  Clients never send any data to
> > the server, indeed they may shutdown that side of the connection and
> > just receive data.
> > 
> > The only way I can find to discover that a client has disappeared is by
> > trying to send them a message and getting an error because they've
> > closed the socket or died completely.  At that point I can reap the
> > resources and remove them from the client list.  This is problem because
> > of the "months between messages" thing.  A lot of clients can come and
> > go during those months and I've got this ever-growing list of open
> > socket descriptors because I never had anything to say the whole time
> > they were connected.
> > 
> > By trial and error I've discovered that I can sort of "poll" for their
> > presence by writing a zero-length message.  If the other end of the
> > connection is gone I get the expected error and can reap the client,
> > otherwise it appears to quietly write nothing and return zero and have
> > no other side effects than polling the status of the server->client side
> > of the pipe.
> > 
> > My problem with this "polling" is that I can't find anything in writing
> > that sanctions this behavior.  Would this amount to relying on a
> > non-portable accident of the current implementation?  
> > 
> > Also, am I missing something simple and there's a cannonical way to
> > handle this?  In all the years I've done client/server stuff I've never
> > had quite this type of interaction (or lack thereof) between client and
> > server before.
> 
> Check for the IN events as well. I would not trust the mere presence
> of the IN in the poll result, but consequent read should return EOF
> and this is good indicator of the dead client.

You can't use EOF on a read() to determine client life when the nature
of the client/server relationship is that clients are allowed to
shutdown(fd, SHUT_WR) as soon as they connect because they expect to
receive but never send any data.

On the other hand, Alfred's suggestion of using poll(2) rather than
select(2) worked perfectly.  Polling with an events mask of zero results
in it returning POLLHUP in revents if the client has closed the socket.

-- Ian





Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?1359481565.93359.160.camel>