Что такое хороший способ подключения нескольких клиентов к серверу? - PullRequest
4 голосов
/ 24 декабря 2009

Поскольку есть несколько способов подключения мультиклиентов к серверу, таких как: fork, select, threads и т. Д. Я был бы рад, если бы вы могли описать, как лучше подключить несколько клиентов к серверу?

Ответы [ 8 ]

6 голосов
/ 24 декабря 2009

Загляните на страницу C10K , чтобы получить отличный обзор и сравнение структур и стратегий ввода-вывода.

4 голосов
/ 24 декабря 2009

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

Я рекомендую сервер быть пассивным (клиенты будут подключаться к нему, а не к серверу, подключающемуся к клиентам), как это обычно делается в Интернете. Следовательно, он также будет иметь сокет слушателя.

2 голосов
/ 24 декабря 2009

Есть как минимум два варианта.

  • Создать сокет прослушивания.
  • Подождите, пока соединение.
  • Создать поток для обработки соединения.

или

  • Создайте сокет прослушивания и дождитесь его с помощью select ().
  • Если активируется прослушивающий сокет fd, создайте новое соединение и добавьте новый fd к вызову select.
  • Если соединение fd становится активным, обработайте его.

Если вы понимаете темы, первым вариантом может быть более чистый подход. Второй подход требует некоторого управления fd (например, прослушивание или соединение), но может выполняться в одном потоке.

what do you mean by this <<the first alternative might be a cleaner approach>>? can you explain pls?

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

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

2 голосов
/ 24 декабря 2009

Один простой совет: избегайте использования fork, поскольку он создает тяжелый процесс, вместо этого используйте потоки, которые намного легче и используют то же пространство памяти, что и созданные процессы.

1 голос
/ 24 декабря 2009

Если вы используете Windows, то самый эффективный способ обработки большого количества клиентов - это построить сервер на основе асинхронных портов ввода-вывода и портов завершения ввода-вывода. Это позволяет эффективно обслуживать множество (10 тысяч) клиентов с небольшим количеством потоков (4?).

Некоторые люди считают, что асинхронный характер модели порта завершения ввода / вывода немного сложен для понимания, но у меня есть бесплатная платформа исходного кода C ++, которую вы можете загрузить с здесь , чтобы начать работу. Если вы используете управляемый код, то все API асинхронных сокетов в .Net Framework используют порты завершения ввода / вывода «под капотом».

Модель порта завершения ввода / вывода хорошо масштабируется, потому что это примитив операционной системы, созданный с нуля для обеспечения эффективности; он знает, работают ли связанные с ним потоки или ожидают, и поэтому может управлять количеством потоков, которые он позволяет обрабатывать «завершения» одновременно. Он также использует потоки в порядке fifo, так что если мало работы, то будет меньше переключаемых контекстов, так как будет использовано только минимальное количество потоков (вместо того, чтобы планировать рабочие элементы во всех потоках и вызывать все их стеки). оставаться в памяти). Напротив, ваш собственный пул потоков должен быть менее эффективным, поскольку вы не обладаете тем же уровнем знаний о потоках, что и IOCP. Выбор часто страдает от ограничения количества поддерживаемых сокетов, что означает, что для истинной масштабируемости вам необходимо создать сложный код поверх вашего выбора, чтобы иметь возможность управлять большим количеством клиентов. Использование потока для каждой модели подключения гораздо менее эффективно, поскольку новые потоки не только регулярно запускаются и останавливаются, но и у вас меньше возможностей контролировать количество потоков в процессе одновременно - потоки являются относительно тяжелыми ресурсами, если учитывать в их стековом пространстве и т. д. Как только у вас будет больше потоков, чем ядер ЦП, вы будете терять время на переключение контекста (которого IOCP часто избегает полностью). Наконец, создание нового процесса для каждого соединения является еще более тяжелым, чем для потока на модель соединения, и лично я не вижу причин считать это допустимым вариантом в современной ОС.

1 голос
/ 24 декабря 2009

, если ваша программа работает на Windows. Полностью избегайте потоков и процессов и используйте асинхронную модель программирования сокетов. На сегодняшний день это самый эффективный (и самый простой способ) сетевой обмен данными.

1 голос
/ 24 декабря 2009

Я знаю в C, что fd_select предлагает эту возможность опроса сокетов. Не уверен, но я предполагаю, что у C # есть намного более хороший способ сделать это.

0 голосов
/ 04 марта 2011

Глава 30 Сетевое программирование Unix представляет альтернативы проектирования клиент / сервер. Книга UNP - лучшее начало сетевого программирования.

...