Неблокирующая розетка подключения в Windows без ConnectEx
Мне нужно инициировать тысячи клиентских подключений в одном процессе, главное ограничение, которое мне нужно обойти, это драйвер не поддерживает ConnectEx, поэтому у меня не может быть чистого решения IOCP.
Моей первой мыслью был пул потоков для обработки соединений, где каждый дескриптор может обрабатывать до 64 соединений, используя простую семантику соединения / выбора, и после подключения продолжайте работу с IOCP. Но это не может работать; после запуска select я не могу добавить еще один сокет в FD_SET. Поэтому я должен был бы установить сокеты на неблокирующие и опрашивать их.
Лучшее решение может быть самым простым; один подключающийся клиент на поток. Предполагая, что я могу поддерживать разумную скорость соединения, количество потоков в пуле может быть небольшим.
Это странная ситуация, в идеале драйвер будет поддерживать ConnectEx, но это не так (пока), и мне нужно обойти это как можно лучше.
Есть ли другой способ?
1 ответ
Во-первых, можно сломать select
используя фиктивный сокет (например, сокет UDP, подключенный к себе), хотя это может быть дорогостоящим в вашем случае.
Если у вас есть окно, которое может обрабатывать сообщения, вы можете использовать WSAAsyncSelect
получать асинхронные уведомления для connect
, (обратите внимание, что это также автоматически делает ваш сокет неблокирующим, что требует еще одного вызова WSAAsyncSelect
и вызов ioctlsocket
отключить).
Не имея этого, вы можете использовать WSAEventSelect
хотя вы обнаружите, что это ограничивает вас до 64 сокетов за ожидание (так как это верхний предел WaitForMultipleObjects
). Это также сделает ваш сокет неблокирующим, что вы можете отменить аналогично тому, что сделано для WSAAsyncSelect
,
(Как полное примечание, вы можете увеличить количество обработанных сокетов select
определяя FD_SETSIZE
перед включением winsock2.h
)