Я бы рекомендовал вместо этого использовать перекрывающийся IO . Затем вы можете запустить WSARecv()
и предоставить функцию обратного вызова, которая будет вызываться после завершения операции. Более того, поскольку она будет вызываться только тогда, когда ваша программа находится в состоянии ожидания с оповещением, вам не нужно беспокоиться о блокировках, как если бы вы работали в многопоточном приложении (при условии, что вы запускаете их в своем основном потоке).
Обратите внимание, однако, что вам do необходимо часто входить в такое состояние ожидания с предупреждением. Если это ваш поток пользовательского интерфейса, обязательно используйте MsgWaitForMultipleObjectsEx()
в цикле сообщений с флагом MWMO_ALERTABLE
. Это даст вашим обратным вызовам шанс на запуск. В потоках, не связанных с пользовательским интерфейсом, регулярно вызывайте любую из функций ожидания , переводящих вас в состояние ожидания с оповещением.
Также обратите внимание, что модальные диалоги, как правило, не переходят в состояние ожидания с оповещением, поскольку они имеют собственный цикл обработки сообщений, который не вызывает MsgWaitForMultipleObjectsEx()
. Если вам нужно обрабатывать сетевой ввод-вывод при отображении диалогового окна, все сетевые операции ввода-вывода выполняются в выделенном потоке, который регулярно переходит в состояние ожидания с оповещением.
Если по какой-либо причине вы не можете использовать перекрывающийся ввод-вывод - обязательно используйте блокировку select()
. Использование неблокирующего recv()
в бесконечном цикле - непростительная трата процессорного времени. Однако переведите сокеты в неблокирующий режим - иначе, если прибывает один байт и вы пытаетесь прочитать два, вы можете неожиданно заблокировать блокировку.
Возможно, вы захотите использовать библиотеку для абстрагирования от привередливых деталей. Например, libevent или boost :: asio .