Работает для системного вызова accept()

#c #sockets #testing #client-server

#c #сокеты #тестирование #клиент-сервер

Вопрос:

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

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

Поскольку я новичок в программировании сокетов, я не уверен, что «accept» является правильным системным вызовом для использования. Кроме того, каким должно быть значение BACKLOG в listen to make, чтобы увидеть нагрузку, с которой может справиться сервер.

Есть помощь?

Комментарии:

1. Вы используете потоки или select ?

2. Звучит как вопрос домашнего задания…

3. Это не вопрос домашнего задания. Это то, что я делаю, чтобы понять системные вызовы в целом. Я раньше не работал на системном уровне.

Ответ №1:

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

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

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

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

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

Ответ №2:

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

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

Основная идея заключается в следующем:

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

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

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

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

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

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