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