приложение winsock и многопоточность - прослушивание события сокета из другого потока

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

мне было интересно, как лучше всего реализовать это:

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

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

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

также я читал о WSAAsyncSelect, но я видел, что это используется для отправки сообщений в окно. нет ли чего-то подобного для других тем? (ну, я думаю, БТР...)

Спасибо!


person roybj    schedule 04.12.2012    source источник
comment
функция PostThreadMessage   -  person Arno    schedule 04.12.2012


Ответы (2)


Используйте порты завершения ввода/вывода. См. функции CreateIoCompletionPort() и GetQueuedCompletionStatus() API Win32 (в разделе "Функции управления файлами"). В этом случае дескрипторы сокетов используются вместо дескрипторов файлов.

person Dave    schedule 14.04.2013

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

Решение о блокировке или неблокировке сокетов зависит от уровня масштабируемости, которого должны достичь ваши приложения. Если вашему приложению необходимо поддерживать сотни входящих подключений, использование подхода «поток на сокет» не будет очень разумным. Вам лучше перейти на реализацию на основе портов ввода-вывода, что сделает ваше приложение чрезвычайно масштабируемым при дополнительной сложности кода. Однако, если вы предвидите только несколько десятков подключений в любой момент времени, вы можете использовать модель асинхронных сокетов, используя события или сообщения Win32. Подход, основанный на событиях Win32, не очень хорошо масштабируется за пределами определенного предела, поскольку вам придется управлять несколькими потоками, если количество одновременных сокетов превышает 63 (поскольку WaitForMultipleObjects может поддерживать только максимум 64 сокета). Однако механизм, основанный на сообщениях Windows, не имеет этого ограничения. OHOH, подход, основанный на событиях Win32, не требует для работы окна графического интерфейса.

Ознакомьтесь с WSAEventSelect вместе с WSAAsyncSelect документацией по API в MSDN.

Вы также можете взглянуть на пакет boost::asio. Он обеспечивает аккуратную (хотя и немного сложную) абстракцию C++ над API сокетов.

person Hari Mahadevan    schedule 11.12.2013