Порты завершения ввода-вывода и сокет WSARecv()

Я пытаюсь понять, как IOCP работает с сокетами. Мне нужно понять, так ли они работают:

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

Теперь я хочу знать, как это связано с получением данных из сокета, поэтому, когда я вызываю WSARecv(), что именно происходит, возвращает ли WSARecv() сразу, когда я его вызываю (не блокирует), а затем позже, когда данные поступают в WSARecv(), я получаю уведомление о получении данных?


person user4582812    schedule 21.02.2015    source источник


Ответы (2)


Да, это то, что происходит.

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

person John    schedule 22.02.2015

Если вы хотите узнать больше о IOCP, WSARecv() и сокетах, ознакомьтесь с моим примером проекта, который я сделал, чтобы разобраться в этом вопросе.

Нажмите здесь, чтобы перейти к коду сервера завершения сокетов

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

Как только GetQueuedCompletionStatus() возвращает значение, которое теперь разблокировано, процесс движется вперед, оценивая содержимое буфера. Просто введите свой код, как вы хотите обрабатывать буфер.

Что касается WSARecv(), вызов этой функции инициирует API-интерфейс сокета для заполнения буфера данными. Поскольку он перекрывается, WSARecv() не будет блокироваться и сразу же вернется. Есть способ узнать, когда возникает событие завершения, просто вызвав GetQueuedCompletionStatus().

person benG    schedule 01.04.2015