Установка sockopt для клиентского сокета, возвращенного из accept()
Я пытаюсь установить параметры сокета для клиентского сокета, возвращенного из accept()
функция. Но они не устанавливаются правильно.
Моя цель - установить время ожидания клиента после определенного периода бездействия. Но сервер все еще должен быть в состоянии принять другие клиентские соединения.
Ниже мой код, где я установил опцию сокета. Подскажите, пожалуйста, что не так?
while ((new_sock_fd = accept(socket_fd, (struct sockaddr *) &cli_addr, &clilen)) > 0)
{
if (new_sock_fd < 0)
printf("Accept Error");
else
{
struct timeval timeout;
timeout.tv_sec = 10;
timeout.tv_usec = 0;
if (setsockopt(new_sock_fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
error("setsockopt failed\n");
if (setsockopt(new_sock_fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0)
error("setsockopt failed\n");
pthread_create(&thread, NULL, client_handler, (void *) (intptr_t)new_sock_fd); //intptr_t is big enough to hold the integer prt
}
}
1 ответ
Моя цель - установить время ожидания клиента после определенного периода бездействия. [...] Можете ли вы предложить, что, если не так..?
Я подозреваю, что неправильно то, что вы неправильно понимаете, для чего предназначены SO_RCVTIMEO и SO_SNDTIMEO. Со страницы руководства:
SO_RCVTIMEO и SO_SNDTIMEO Укажите таймауты получения или отправки до сообщения об ошибке. Аргумент является структурой timeval. Если функциональные блоки ввода или вывода на этот период времени и данные были отправлены или получены, возвращаемое значение этой функции будет количеством переданных данных; если данные не были переданы и тайм-аут был достигнут, то возвращается -1 с errno, установленным в EAGAIN или EWOULDBLOCK, или EINPROGRESS (для connect(2)), как если бы сокет был указан как неблокирующий. Если тайм-аут установлен на ноль (по умолчанию), то операция никогда не прекратится.
... но звучит так, как будто вы хотите, чтобы TCP-соединение автоматически закрывалось через определенное время без трафика на TCP-соединении, что не то же самое, что принудительный вызов send() или recv() вернуться через указанное количество времени.
Если вы ищете механизм закрытия простаивающего TCP-соединения, вы можете реализовать это самостоятельно, записывая текущее время, когда данные отправляются или принимаются в сокете. В более позднее время (например, после истечения времени ожидания send() или recv()) вы можете вычесть записанный вами последний просмотренный трафик из текущего времени; если разница больше вашего значения времени простоя, вызовите close() для сокета самостоятельно.