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>