Если я сделаю вызов приема через WSARecv, рабочий поток работает как функция обратного вызова?
См. Сообщение @valdo.Данные завершения поставлены в очередь в ваш пул потоков, и один из них будет подготовлен для их обработки.
'Я имею в виду, выкапывает ли получаемый вызов только после завершения?'Да - отсюда и название.Обратите внимание, что значение «завершено» может отличаться.в зависимости от протокола.В случае TCP это означает, что некоторые одноранговые байты данных были получены от однорангового узла.
'Содержит ли переменная lpNumberOfBytes (из GetQueuedCompletionStatus) количество полученных до сих пор байтов или общее количество полученных байтов?'Он содержит количество байтов, полученных и загруженных в буферный массив, предоставленный только в этом завершении IOCP.
«Как избежать переполнения, я подумал о динамически распределенных структурах буфера, но опять же, как мне узнать, насколько большим будет пакет?»Вы не можете получить переполнение, если вы предоставите буферные массивы - потоки ядра, которые загружают буфер, не будут превышать переданную длину буфера.На уровне приложений, учитывая потоковую природу TCP, вам решать, как обрабатывать буферные массивы в пригодные для использования блоки протокола уровня приложения.Используя свои знания о предоставляемых услугах, вы должны принять решение о подходящей схеме управления буфером.
Последний сервер IOCP был, как правило, универсальным.Я использовал массив буферных пулов и пул объектов «буфер-носитель», выделяемых при запуске (вместе с пулом объектов сокетов).Каждый пул буферов содержал буферы разного размера.После нового соединения я выпустил WSARecv, используя один буфер из наименьшего пула.Если этот буфер был полностью заполнен, я использовал буфер из следующего по величине пула для следующего WSARecv и т. Д.
Затем возникает проблема с порядковыми номерами, необходимыми для предотвращения неправильной буферизации с несколькимиобработчик потоков: (