How to determine whether connection to socket was closed
I am writting the socket with C++ under Linux. I have a question. How I can find out whether the client closed the connection.
Especially in the situation in which the server accepted the c开发者_如何学编程lient and started to wait for some data from client. But the client does not send anything and just closes the connection to server. In this situation my server is waiting forever for some data.
Here is example of my program:
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,256);
n = read(newsockfd,buffer,255);
Also I have several sockets on my server. I need to know to which socket the client closed the connection.
If the client closed the connection, n = read(newsocketfd, buffer, 255)
will return 0.
You can set a socket to timeout using the "setsockopt". You'll need to #include sys/socket.h
and sys/types.h
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);
You'll want SO_RCVTIMEO or SO_SNDTIMEO for optname. For optval, you'll want a pointer to struct timeval, and level is SOL_SOCKET. For example:
struct timeval tv;
tv.tv_sec = 10;
tv.tv_usec = 0;
setsockopt(mySocket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
Will set the socket to time out on send operations after 10 seconds.
You want to use select or poll on your sockets, not just a read. That way a slow client doesn't block the entire server.
You will also want to keep track of all your sockets.
My basic pseudo-code for multi-socket servers looks like:
<create/bind serversocket, listen on it, add it to fd_set>
while ( running )
{
nd = select( maxfd, fd_set, null, null, timeout )
if ( nd == 0 )
continue; // timeout - do periodic processing
if ( fd_isset( fd, serversocket )
{
do the accept on the server socket and add new socket to the fd_set
}
if ( isset( fd, clientsocket ) )
{
now you know data is available on the socket, so you can read from it
a return of 0 on the socket indicates the socket was closed
in which case you should close your end and remove socket from fd_set
}
}
I'm leaving out a lot of details but that's the basic structure.
精彩评论