Date: Fri, 23 Aug 1996 12:06:14 -0600 (MDT) From: Nate Williams <nate@mt.sri.com> To: hackers@freebsd.org Cc: nate@rocky.mt.sri.com Subject: Non-blocking I/O on sockets and closed sockets? Message-ID: <199608231806.MAA07694@rocky.mt.sri.com>
next in thread | raw e-mail | index | archive | help
I need to setup my sockets as non-blocking to avoid some problems, but
it brings up a problem of determining if the remote end has closed the
connection. Normally, if you run select() on a FD, and the subsequent
read() call returns 0 you can assume the socket is dead. However, with
non-blocking I/O a read of 0 does *NOT* mean the socket is dead.
Will read() return a negative error code on a socket if the socket is
closed/dead? I've looked in Steven's and in the obvious manpages, but
nothing jumps out at me.
Here's the code snippet which should explain what goes on.
(error checking removed)
void do_socket(short inport)
{
struct sockaddr_in addr;
int s_sock, d_sock, flag;
/* No data yet */
d_sock = -1;
s_sock = socket(AF_INET, SOCK_STREAM, 0);
port = htons(inport);
#ifdef DEBUG
flag = 1;
setsockopt(s_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof flag);
#endif
addr.sin_family = AF_INET;
addr.sin_port = htons(inport);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind(s_sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
/* Make sure the socket is in non-blocking mode */
flag = fcntl(s_sock, F_GETFL, 0);
fcntl(s_sock, F_SETFL, flag|O_NONBLOCK);
/* Will not block */
listen(s_sock, 1);
/* Wait until we get some input */
for (;;) {
fd_set input_fds;
FD_ZERO(&input_fds);
if ( d_sock == -1 )
FD_SET(s_sock, &input_fds);
else
FD_SET(d_sock, &input_fds);
if ( (i = select(FD_SETSIZE, &input_fds, 0, 0, 0)) < 0 ) {
if ( errno == EINTR )
continue;
perror("Select loop");
exit(1);
}
/* Connection request? */
if ( d_sock == -1 ) {
int addrlen = sizeof(addr);
d_sock = accept(s_sock, (struct sockaddr *)&addr, &addrlen);
/* non-blocking mode */
flag = fcntl(d_sock, F_GETFL, 0);
fcntl(d_sock, F_SETFL, flag|O_NONBLOCK);
} else {
char lbuff[255];
/*
* We may have more data than can fit in lbuff, so read in lbuff
* size chunks.
* XXX - How do we determine if the socket is closed?
*/
do {
i = read(data->stream_sock, lbuff, 512);
if ( i > 0 )
save_data(lbuff, i);
} while ( i > 0 );
}
}
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199608231806.MAA07694>
