Каков наилучший способ обработки новых клиентов с помощью select () на сервере? - PullRequest
1 голос
/ 23 октября 2011

Я хочу написать асинхронный сокет-сервер на C, но прежде чем я это сделаю, я провожу некоторые исследования.Глядя на пример сокета select (), показанный здесь: http://www.gnu.org/s/hello/manual/libc/Server-Example.html#Server-Example Я вижу, что пример программы будет принимать только одного клиента на цикл выбора (если я правильно читаю).Таким образом, если есть 20 клиентов и еще два пытаются подключиться, будет ли он принимать только 21-го клиента, а затем обработать остальные 20 (наихудший случай, если все 20 других требуют чтения), и ТО принять 22-го?Было бы лучше, если бы я разорвал цикл после принятия клиента, чтобы он снова мог выбрать () и позаботиться обо всех ожидающих клиентов перед обработкой подключенных?Или это побеждает цель использования select ()?Спасибо.

Ответы [ 3 ]

3 голосов
/ 23 октября 2011

Шаблон сервера, показанный в примере, на который вы ссылаетесь, в порядке;нет никаких существенных проблем, связанных с тем, что цикл принимает только один сокет за итерацию.

Ключевым моментом, который следует иметь в виду, является то, что в правильно спроектированном цикле select (), only поместить процесс в когда-либо блок внутри вызова select ().В частности, при правильном кодировании сервер никогда не заблокирует внутри send (), recv () или accept ().Лучше всего установить все сокеты в неблокирующий режим (через fcntl (fd, F_SETFL, O_NONBLOCK)), чтобы гарантировать такое поведение.

Учитывая, что точный порядок «какие клиенты обслуживаются первыми в любомособая итерация цикла событий "не имеет значения, потому что все клиентские сокеты обрабатываются очень скоро после того, как у них есть данные, готовые для чтения (или буферное пространство, готовое для записи), и все новые соединения принимаются быстро.

1 голос
/ 23 октября 2011

Вы можете использовать poll () на прослушивающем сокете после accept (), чтобы узнать, есть ли еще клиенты, ожидающие подключения.

Обратите внимание, что число одновременных попыток соединения обрабатывается параметром backlog для прослушивания (server_sock, backlog) - в примере, на который вы ссылаетесь, backlog равен 1.

1 голос
/ 23 октября 2011

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

...