Как определить, было ли закрыто соединение с сокетом
Я пишу сокет с C++ под Linux. У меня есть вопрос. Как я могу узнать, закрыл ли клиент соединение.
Особенно в ситуации, когда сервер принял клиента и начал ждать каких-то данных от клиента. Но клиент ничего не отправляет и просто закрывает соединение с сервером. В этой ситуации мой сервер вечно ждет каких-то данных.
Вот пример моей программы:
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,256);
n = read(newsockfd,buffer,255);
Также у меня есть несколько сокетов на моем сервер. Мне нужно знать, к какому разъему клиент закрыл соединение.
3 ответов:
Вы можете установить сокет на таймаут, используя "setsockopt". Вам нужно будет #включить
sys/socket.hиsys/types.hint setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);Вы хотите SO_RCVTIMEO и SO_SNDTIMEO для optname. Для optval вам понадобится указатель на struct timeval, а level-SOL_SOCKET. Например:
struct timeval tv; tv.tv_sec = 10; tv.tv_usec = 0; setsockopt(mySocket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));Установит сокет на тайм-аут для операций отправки через 10 секунд.
Вы хотите использовать select или poll на ваших сокетах, а не просто чтение. Таким образом, медленный клиент не блокирует весь сервер.
Вы также захотите отслеживать все ваши сокеты.
Мой основной псевдокод для серверов с несколькими сокетами выглядит следующим образом:
Я опускаю много деталей, но это основная структура.<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 } }
Comments