2009-02-07 6 views
4

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

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

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

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

Заранее благодарен! :-)

ответ

5

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

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

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

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

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

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

+0

# Джеффри Рихтер AysncEnumerator # ничего себе !!! – divinci

3

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

2

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

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

3

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

2

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

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

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

+0

Очень полезные статьи. Большое спасибо. – haste

+0

О, одна вещь, о которой я не упоминал; проблема сортировки из потока IOCP в поток GUI помогает (в моих рамках) в том, что и объекты оболочки оболочки, и объекты буфера подсчитываются по ссылке; просто AddRef() и отправьте их как параметры в сообщении Windows ... –

Смежные вопросы