Установка 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() для сокета самостоятельно.

Другие вопросы по тегам