Наиболее подходящая модель асинхронного сокета для клиента обмена мгновенными сообщениями? - PullRequest
4 голосов
/ 07 февраля 2009

Я работаю над клиентом обмена мгновенными сообщениями на C ++ (Win32) и экспериментирую с различными моделями асинхронных сокетов. До сих пор я использовал WSAAsyncSelect для получения уведомлений через главное окно. Однако я столкнулся с некоторыми неожиданными результатами при порождении Winsock дополнительно 5-6 потоков (в дополнение к исходному потоку, созданному при вызове WSAAsyncSelect) для одного отдельного сокета.

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

Я ищу совет относительно того, какой подходящей моделью асинхронного сокета может быть многопротокольный IM-клиент, который должен уметь обрабатывать примерно 10-20 + соединений (в зависимости от количества протоколов и дизайн протокола и т. д.), хотя я не использую чрезмерное количество потоков - я очень заинтересован в производительности и снижении использования ресурсов.

Я искал порты завершения ввода-вывода, но из того, что я собрал, это кажется излишним. Я был бы очень признателен за информацию о том, каким может быть подходящее решение для сокетов!

Заранее спасибо! : -)

Ответы [ 5 ]

5 голосов
/ 07 февраля 2009

Существует четыре основных способа обработки нескольких одновременных сокетов.

  1. Мультиплексирование, которое использует select () для опроса сокетов.
  2. AsyncSelect, который в основном то, что вы делаете с WSAAsyncSelect.
  3. Рабочие потоки, создавая отдельный поток для каждого соединения.
  4. Порты завершения ввода-вывода или IOCP. dp упоминает их выше, но в основном это специфический для ОС способ обработки асинхронного ввода-вывода, который имеет очень хорошую производительность, но это немного запутывает.

То, что вы выбираете, часто зависит от того, куда вы планируете пойти. Если вы планируете портировать приложение на другие платформы, вы можете выбрать # 1 или # 3, поскольку select не сильно отличается от других моделей, используемых в других ОС, и большинство других ОС также имеют концепцию потоков (хотя они могут действовать по-другому). IOCP, как правило, специфичен для Windows (хотя в Linux теперь также есть некоторые функции асинхронного ввода-вывода).

Если ваше приложение предназначено только для Windows, то вы в основном хотите выбрать лучшую модель для того, что вы делаете. Скорее всего, это будет №3 или №4. # 4 является наиболее эффективным, так как он вызывает обратно в ваше приложение (похоже, но с лучшей производительностью и меньшим количеством проблем для WSAsyncSelect).

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

Если бы вы разрабатывали это в управляемом коде, я бы посоветовал вам взглянуть на AysncEnumerator Джеффри Рихтера, но вы выбрали C ++, у которого есть свои плюсы и минусы. Многие люди написали различные сетевые библиотеки для C ++, может быть, вам стоит потратить некоторое время на изучение некоторых из них.

3 голосов
/ 08 февраля 2009

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

3 голосов
/ 07 февраля 2009

рассмотрите возможность использования библиотеки ASIO, которую вы можете найти в boost (www.boost.org).

2 голосов
/ 09 февраля 2009

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

Последняя версия кода и ссылки на оригинальные статьи доступны по адресу здесь .

И мои взгляды на сравнение моего фреймворка с Boost :: ASIO можно найти здесь: http://www.lenholgate.com/blog/2008/09/how-does-the-socket-server-framework-compare-to-boostasio.html.

2 голосов
/ 07 февраля 2009

В некоторых случаях порты завершения ввода-вывода (IOCP) излишни, но, если честно, я считаю, что модель асинхронных сокетов проще в использовании, чем альтернативные (выбор, неблокирующие сокеты, перекрывающийся ввод-вывод и т. Д.).

API IOCP может быть понятнее, но, как только вы его пройдете, я думаю, что его будет проще использовать. В те времена самым большим препятствием была поддержка платформы (для этого требовалась ОС на базе NT - то есть Windows 9x не поддерживала IOCP). С этим давно ушедшим ограничением, я бы его рассмотрел.

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