Работа для системного вызова accept () - PullRequest
2 голосов
/ 14 ноября 2011

Мне нужно написать программу, которая проверит, сколько клиентов может подключиться к одному серверу (сокету) в C.

Я использовал руководство Биджа по программированию в качестве справочного материала и понял, что после того, как один клиент подключается к серверу, больше клиентов не могут одновременно отправлять сообщения на один и тот же сервер. Только после того, как первое соединение будет закрыто, будет доставлено сообщение с ошибкой от второго клиента.

Поскольку я новичок в программировании сокетов, я не уверен, что "accept" - это правильный системный вызов, который нужно использовать. Кроме того, какое значение BACKLOG должно быть в прослушивании, чтобы увидеть нагрузку, с которой может справиться сервер.

Любая помощь?

Ответы [ 2 ]

2 голосов
/ 14 ноября 2011

В разделе 7.2 руководства Биджа описан способ сделать это, который сначала изучают большинство программистов на Си. Пример в конце раздела 7.2 должен быть именно тем, что вы хотите.

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

Основная идея такова:

1) Настройте базовые структуры для отслеживания клиентов, инициализируйте их, чтобы отразить тот факт, что у вас нет клиентов.

2) Настройте гнездо прослушивания для новых подключений.

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

4) Обращайся, что бы ни случилось. Если новый клиент пытается подключиться, accept подключите и обновите структуры отслеживания. Если данные были получены от клиента, посмотрите, завершает ли он команду, и, если это так, обработайте ее. Если один из ваших клиентов закрыл соединение или произошла ошибка в этом соединении, очистите его, закрыв сокет и обновив отслеживание.

5) Вернитесь к шагу 3.

Это называется «мультиплексирование ввода / вывода». Есть и другие способы сделать это, но именно так большинство программистов на С сначала учатся.

2 голосов
/ 14 ноября 2011

accept() - правильный системный вызов.Он возвращает новый файловый дескриптор, связанный с новым входящим соединением, при этом оставляя исходный сокет подготовленным для приема большего количества соединений.

Однако, как только вы приняли этот входящийДля подключения обычно используется основной процесс:

  1. создайте поток для обработки этого сокета
  2. fork новый процесс, который наследует новый дескриптор файла.
  3. используйте select(), epoll() и т. д., чтобы опросить чтение на этом сокете

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

Параметр backlog для listen() служит только для того, чтобы сообщить ядру, сколько сокетов может быть оставлено в их первоначальном состоянии «подключения» до этого - обычно нет необходимости настраиватьэто очень много.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...