[comp.protocols.tcp-ip] Final Report on 0-byte recv

robert@SPAM.ISTC.SRI.COM.UUCP (06/15/87)

	Here is a summary of replies regarding my problem with
0-byte recv()'s on TCP sockets.  As a capsule review, all of the
answers I received were of the opinion that reading 0 bytes was a
UNIX-like indication of EOF.  My reply to this is twofold;

    First, in my humble opinion a socket is not *really* a file.  The
    file descriptor interface is a UNIX-ism for the TCP connection
    abstraction, but shouldn't necessarily follow all the rules for
    file I/O.  In particular, I believe that since the TCP socket is
    a logical connection, the concept of a socket 'going bad' is more
    apt than 'reaching EOF'.  Of course, my dispensation of file status
    on a socket is somewhat hypocritical, as I have in the past complained
    that non-blocking sockets *don't* act like files in regards to read()
    and write() (> 2k byte transfers fail;  it's a 4.2 bug according to Mike
    Karrels).

    Second, select() is still indicating data as being there, so the
    claim that EOF is encountered seem's rather bogus to me.  As I
    mentioned, this will occur for quite a while, if not forever; I've
    watched upto 600 consecutive read()s produce 0, even though
    select() claimed that data was there.  I now close and restart
    the socket after 100 0-byte read()s, and will probably close
    and restart after even 1 based on what I've read on the net.
    This feature of select may be the result of 'exceptfds' not
    being implemented under 4.2.

Many thanks to everyone who provided input,

Robert Allen,
robert@spam.istc.sri.com

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

::::::::::::::
tcp_mail/1
::::::::::::::
From: Steve Schoch <schoch@ames.arpa>
To: robert@spam.istc.sri.com
Subject: Re: Problems with TCP/IP sockets under 4.2.

In article <8706111552.AA08325@spam.istc.sri.com> you write:
>    The problem is this; if the client process goes away abruptly, the server
>    socket does not know about it.  Further, if a select() is called on the
>    (now supposedly 'dead') file-descriptor for reading, it will indicate
>    that there is data there.  If the fd is read, 0 bytes are received;

This is correct.  The way I interpret select() is that it returns whenever
a read will return without blocking.  In unix, a read of 0 bytes always
indicates EOF and you should not continue to read from it.  Exceptions are
files that are growing, in which case you should sleep before the next read,
and ttys, which are kind of special in that you can read past EOF and get the
next character typed after the ^D.

>    no error condition is indicated by the recv.  I have seen upto 600 repeated
>    select()'s and recv()'s without getting a -1 from recv.

That's because it's not an error for the client process to exit, it's an
end-of-file, i.e., no more data is available.  When your program reads an
EOF it should not attempt to read any more data as there will never be
any more.

::::::::::::::
tcp_mail/3
::::::::::::::
From: mankin@gateway.mitre.org (Allison J. Mankin)
To: robert@spam.istc.sri.com
Subject: Re:  Problems with TCP/IP sockets under 4.2.

Robert,

You are having a problem because the server's socket registers the
client's change of status (closed or gone, whatever) with its read
bit.  The zero recv instead of an error is offered *on purpose* by
the system to indicate that the change of status was due to a proper
close, that is, a TCP FIN was received from the client.

So, it is a undocumented feature that's causing you trouble, rather
than a bug.  It is this way in both 4.2 and 4.3 derived systems.

One way to deal with it is to keep track of the state of sockets
and take them off of select the first time that the zero recv 
indicates the peer closed--there can be no more data to recv anyway.

			Allison
::::::::::::::
tcp_mail/4
::::::::::::::
To: Robert Allen <robert@spam.istc.sri.com>
Subject: Re: Problems with TCP/IP sockets under 4.2. 
From: John Hight <hight@tsca.istc.sri.com>


Robert,

I can't help with your problem, however, I think I might have experienced
similar problems some time back, so I would be interested in any
meaningful responses you get back that perhaps are sent out over the
tcp/ip list.

John
::::::::::::::
tcp_mail/6
::::::::::::::
From: brd@sun.com (Bill Danielson)
To: robert@spam.istc.sri.com
Subject: Problems with TCP/IP sockets under 4.2

In Unix, any read returning zero bytes means "end of file".  This is way
you can tell when "end-of-file" occurs when, say, reading a disk file.
Unix does not use the -1 return to indicate "end-of-file".

When you are reading from a TCP connection, end-of-file is signalled if
the other side closes the connection.  

If you had done a non-blocking read and no data had been received,
read would have returned -1 and errno = EWOULDBLOCK.  Thus, you can
distinguish between "no data" and "end-of-file".

Bill Danielson