Как определить, было ли закрыто соединение с сокетом? - PullRequest
2 голосов
/ 16 июля 2011

Я пишу сокет с 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 ]

11 голосов
/ 16 июля 2011

Если клиент закрыл соединение, n = read(newsocketfd, buffer, 255) вернет 0.

2 голосов
/ 16 июля 2011

Вы можете установить сокет на тайм-аут, используя "setsockopt". Вам нужно будет #include sys/socket.h и sys/types.h

int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen); 

Вам понадобится SO_RCVTIMEO или SO_SNDTIMEO для optname. Для optval вам понадобится указатель на структуру timeval, а уровень - SOL_SOCKET. Например:

struct timeval tv;
tv.tv_sec = 10;
tv.tv_usec = 0;

setsockopt(mySocket, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); 

Устанавливает время ожидания для сокета при отправке через 10 секунд.

0 голосов
/ 17 июля 2011

Вы хотите использовать 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
   }
}

Я опускаю много деталей, но это основная структура.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...