Что происходит с select (), когда сокет настроен на обработку тайм-аута

Согласно странице руководства для recv(), errno устанавливается в EAGAIN или EWOULDBLOCK, если для приема был установлен тайм-аут с использованием setsockopt(SO_RCVTIMEO).

У меня вопрос: что произойдет, если несколько таких сокетов будут использоваться с select(). Выбрал бы возврат, если время ожидания одного из сокетов истекло из-за бездействия. Что вернет select().

Я пытаюсь реализовать tftp-сервер с функцией определения тайм-аутов. Одним из способов могло быть использование тайм-аута с select(), но тогда мне пришлось бы использовать другое значение тайм-аута для каждого сокета и продолжать обновлять таймер до минимального значения, а затем делать еще немного жонглирования ... и т. Д. И т. Д. .. Просто кажется, много ненужной работы.

PS: tftp-сервер - это одновременный сервер с несколькими клиентами, которые обрабатываются с помощью мультиплексирования ввода-вывода.


person Parth K    schedule 11.04.2019    source источник
comment
вместо этого сделайте розетки неблокирующими.   -  person Antti Haapala    schedule 11.04.2019
comment
И реализовать тайм-аут с помощью будильников ?? какой еще есть способ?   -  person Parth K    schedule 11.04.2019
comment
Нет, вы должны использовать тайм-аут select.   -  person Antti Haapala    schedule 11.04.2019
comment
Но каждый сокет в select имеет другое значение для тайм-аута.   -  person Parth K    schedule 11.04.2019
comment
И, согласно первому комментарию к этому ответу, использование сигналов тревоги - не лучшая идея.   -  person Parth K    schedule 11.04.2019
comment
Нет, использовать будильники - плохая идея. Вот почему я предлагаю выбрать таймауты. Вам необходимо буферизовать данные для каждого сокета, чтобы вы могли иметь структуру для каждого из них.   -  person Antti Haapala    schedule 11.04.2019
comment
Но тогда мне нужно обновлять структуру timeval для каждого клиента каждый раз, когда возвращается select, и мне придется постоянно проверять список, чтобы проверить минимальное значение, которое будет передано select()   -  person Parth K    schedule 11.04.2019
comment
Храните структуры или указатели на них в очереди. Структура с ближайшим таймаутом всегда будет в начале, поэтому тайм-аут головы .. Добавьте новые таймауты в хвостовой части.   -  person Martin James    schedule 11.04.2019


Ответы (1)


Параметр тайм-аута в select () определяет максимальное время, в течение которого сам вызов select () будет ждать, пока что-то не произойдет, прежде чем вызов вернется, а не то, как долго отдельные сокеты будут ждать перед возвратом ошибки тайм-аута.

Похоже, вы хотите объявить какое-то состояние ошибки, если вы не получаете известие от клиента в течение некоторого периода времени. С UDP вам придется отслеживать это самостоятельно. Для каждого клиента записывайте, когда вы в последний раз слышали о нем. Поместите select () в цикл с таймаутом примерно в 1 секунду, затем каждый раз, когда он возвращается, проверяйте разницу между текущим временем и последним разом, когда вы слышали от каждого клиента. Когда эта разница превышает любой желаемый порог, вы получаете состояние ошибки.

person Seth Noble    schedule 11.04.2019
comment
Вот почему я думаю установить параметр тайм-аута для каждого сокета вместо select(). Насколько я понимаю, если я устанавливаю для отдельных сокетов тайм-аут, а затем вызываю select(), если сокеты истекают, я просто вернусь из select с помощью сокета fd и попытаюсь прочитать сокет. Я предполагаю, что чтение не удастся с EAGAIN, и это моя ошибка. - person Parth K; 11.04.2019
comment
Сокеты UDP не имеют тайм-аута. Сокеты TCP будут отключаться по тайм-ауту, только если вы включите поддержку активности. - person Seth Noble; 12.04.2019