[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::digital_unix

Title:DIGITAL UNIX(FORMERLY KNOWN AS DEC OSF/1)
Notice:Welcome to the Digital UNIX Conference
Moderator:SMURF::DENHAM
Created:Thu Mar 16 1995
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:10068
Total number of notes:35879

9186.0. "What happens to "select(2)" when peer closes connection?" by KZIN::HUDSON (That's what I think) Fri Mar 14 1997 09:46

I have a server that is talking to two clients, and is using select(2)
to wait for one of them to write a message.

Is there a way to tell that one of the clients has closed his end of the
connection?

Experimentation here suggests that when a client does a close in this 
situation, then select() behaves as if that client had sent a zero byte
message - i.e. select returns as soon as the close occurs, FD_ISSET
indicates the socket which was closed, and recv() on that socket returns
zero.

Is it safe to rely on that behaviour?  If so, what should the server do
to distinguish between closed sockets and zero-byte messages?

I can't see anything in the documentation which describes this situation 
(but I'm ready to be pointed at the right place!)

Thanks for any input

nick
T.RTitleUserPersonal
Name
DateLines
9186.1MAY18::bobFor Internal Use OnlyFri Mar 14 1997 10:093
Getting a zero byte read is how it's usually done.

b
9186.2VAXCPU::michaudJeff Michaud - ObjectBrokerFri Mar 14 1997 14:5522
> Is it safe to rely on that behaviour?

	Yes.  BSD style sockets behave like regular file descriptors,
	a read of 0 indicates EOF.

	Do note that Winsock behaves differently, at least Winsock 1.1
	under Windows NT.  A disconnected socket is not considered
	selectable for "read".  You also have to select for "except"
	(at least if you are doing non-blocking connects which is when
	I discovered this).

> If so, what should the server do
> to distinguish between closed sockets and zero-byte messages?

	You didn't indicate which address family/protocol you are
	using.  If you are using TCP/IP, there is no such thing
	as a "message" as TCP/IP is a STREAM abstraction, so that
	also means there is no such thing as a zero-length message.
	If you are talking about AF_DECnet sockets using the SOCK_SEQPACKET
	data abstraction, then see the man page for dnet_eof (or the
	appropriate DECnet specific getsockopt to get the connection
	state).
9186.3KZIN::HUDSONThat's what I thinkMon Mar 17 1997 09:1616
re: .1, .2

Thanks for answering so quickly.

ref: zero byte "message" - I'm not sure of the semantics here, but in my
example, my client did

	socket(AF_INET,SOCK_STREAM,0);
followed by a connect to the relevant port then a
	send(sock_no,NULL,0,0);

which caused my server to fall out of its select() wait, reporting that
it had received a 0 byte "message" from the client.  This effect was
exactly the same when the client did a shutdown(sock_no,2).

nick
9186.4VAXCPU::michaudJeff Michaud - ObjectBrokerMon Mar 17 1997 11:1223
> 	socket(AF_INET,SOCK_STREAM,0);
> followed by a connect to the relevant port then a
> 	send(sock_no,NULL,0,0);
> 
> which caused my server to fall out of its select() wait, reporting that
> it had received a 0 byte "message" from the client.  This effect was
> exactly the same when the client did a shutdown(sock_no,2).

	Again, as I said, there is no such thing as a message, or a
	zero-length message, in TCP (there are no message boundries
	on the "stream" so how can you send a message.  the closest
	thing is the concept of out-of-band data pointer).

	This is the first I've heard that using send(2) with a null
	pointer and 0 byte count results in the server waking from
	it's sleep.  What do you mean by "reporting it had received
	a 0 byte message from the client"?  select(2) does *not* report
	anything about *what* was received on a socket.  Do you really
	mean select(2) reports the socket as readable, and then when
	you do a read/recv that you get back 0 denoting EOF?

	If you could, use tcpdump(8) to get a network trace of your test
	and post it here.  I'm curious ....
9186.5mea culpaKZIN::HUDSONThat's what I thinkTue Mar 18 1997 05:5016
re:.4

I found my coding mistake.  In my client program, my code did a send, and
then closed the socket.  So the server wasn't terminating the select as
a result of the client sending a "zero byte message", it was actually
seeing the result of the close().

I confirmed this by making my client pause in between the send and the
close.  When I called "send(sock_no,NULL,0,0)", nothing happened at the server
end.

Thanks for your input, it's helped me understand things better.  Sorry for
the duff info!

Regards
nick