> Any real socket gurus out there that can answer this question?
> I've got a server process running on an Ultra1, Solaris 2.5.1. It listens
> for connections on a port and forks a copy of itself to handle the
> communications. I set the SO_KEEPALIVE option on the socket, and use
> signal() to catch SIGPIPE. Now, my server process normally runs in a loop,
> calling select() with a timeout - the select call watches for input from a
> number of file descriptors, one of which is the above named connection.
> Here's the problem: if the far end of the socket closes, I don't seem to
> be getting any notification via the SIGPIPE handler. I've looked for
> information that might tell me what the time interval is between
> "KEEPALIVE"s, but none is forthcoming. I've tried looking for it with
> tcpdump, but it doesn't show...
> Is the KEEPALIVE option functional under Solaris 2.5.1, or is this one of
> those "not implemented in this version" problems?
> TIA,
> Bob Scott
From the Socket FAQ: (comp.unix.programmer at RTFM.mit.edu)
2.1. How can I tell when a socket is closed on the other end?
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 */
}
--
Michael