Linux: существует ли чтение или recv от сокета с тайм-аутом?

Как я могу попытаться считать данные с сокета с тайм-аутом? Я знаю, выбор, pselect, опрос, имеет поле тайм-аута, но использование их отключает "tcp быстрый путь" в tcp reno стек.

Единственная идея, которую я имею, состоит в том, чтобы использовать recv (fd..., MESSAGE_DONTWAIT) в цикле

92
задан red0ct 25 April 2019 в 12:35
поделиться

2 ответа

Вы можете использовать функцию setsockopt , чтобы установить тайм-аут для операций приема:

SO_RCVTIMEO

Устанавливает значение тайм-аута, которое указывает максимальное количество времени на ввод функция ожидает завершения. Это принимает временную структуру с количество секунд и микросекунд указание предела продолжительности дождитесь операции ввода, чтобы полный. Если операция приема имеет заблокирован на это время без получив дополнительные данные, он должен возврат с частичным подсчетом или ошибкой установите на [EAGAIN] или [EWOULDBLOCK], если нет данные получены. По умолчанию для этого параметр равен нулю, что означает, что операция получения не должна истекать по тайм-ауту. Эта опция имеет временную структуру. Обратите внимание, что не все реализации разрешить установку этой опции.

// LINUX
struct timeval tv;
tv.tv_sec = timeout_in_seconds;
tv.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);

// WINDOWS
DWORD timeout = timeout_in_seconds * 1000;
setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof timeout);

// MAC OS X (identical to Linux)
struct timeval tv;
tv.tv_sec = timeout_in_seconds;
tv.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);

Сообщается, что в Windows это должно быть сделано до вызова bind . Я экспериментально подтвердил, что это можно сделать до или после bind в Linux и OS X.

175
ответ дан 24 November 2019 в 06:28
поделиться

Установите обработчик для SIGALRM, затем используйте alarm() или ualarm() перед обычным блокирующим recv(). Если сигнал тревоги сработает, recv() вернет ошибку с errno, установленным в EINTR.

-1
ответ дан 24 November 2019 в 06:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: