Как установить разные таймауты для каждого сокета, который выбирает () мониторы? - PullRequest
1 голос
/ 16 сентября 2009

В настоящее время я использую API сокетов BSD. Я хотел бы использовать функцию select () для мониторинга (a) сокета слушателя, который ожидает новых подключений с помощью accept (), и (b) всех клиентских сокетов, созданных с помощью принять () или подключиться (). Я хочу, чтобы у сокета слушателя не было тайм-аута, и я хочу, чтобы у каждого клиентского сокета был тайм-аут 120 секунд.

Возможно ли это с помощью функции select ()? Он принимает только одно значение тайм-аута для всех сокетов, поэтому я предполагаю, что нет. Если это так, я обречен на создание сервера, на котором каждый сокет работает в режиме блокировки в своем собственном потоке?

Ответы [ 3 ]

2 голосов
/ 16 сентября 2009

А почему бы не сделать дизайн этого десятилетия и использовать libevent?

0 голосов
/ 16 сентября 2009

Вам необходимо самостоятельно отслеживать оставшиеся тайм-ауты и передать минимальный тайм-аут на select().

Например, предположим, что вы не хотите, чтобы в сокете прослушивания было время ожидания и время ожидания для каждого соединения составляет 10 минут (время ожидания = 600 секунд). Для каждого соединения отслеживайте время последней активности в этом сокете в секундах, например:

socket  last activity
  1        1950
  2        1990
  3        1500
  4        1998

Оставшееся время ожидания для каждого сокета может быть рассчитано как last + timeout - curtime, поэтому, если текущее время равно 2000 (секундам), оставшееся время ожидания для каждого соединения составляет 550, 590, 100 и 598 соответственно. Минимум из них равен 100, так что в следующий раз вы будете иметь условие тайм-аута в отсутствие другой активности, поэтому передайте его функции select(). Если время ожидания select() истекло, тогда, когда вы пересчитаете оставшееся время ожидания для каждого сокета, вы обнаружите, какие сокеты истекли.

0 голосов
/ 16 сентября 2009

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

Перейти на темы; Вы не можете сделать это с одним select().

...