Как инициализировать WSAOVERLAPPED при использовании IOCP?

Я не уверен, как инициализировать WSAOVERLAPPED при использовании IOCP. Я не думаю, что мне вообще нужно его инициализировать, я только установил WSAOVERLAPPED.hEvent в NULL (тоже не уверен, что это необходимо). Является ли этот код правильным:

// Send data
char buffer[1024];

WSABUF wsaBuf;
wsaBuf.buf = buffer;
wsaBuf.len = 1024;

WSAOVERLAPPED wsaOverlapped;
wsaOverlapped.hEvent = NULL;

WSASend(s, &wsaBuf, 1, NULL, 0, &wsaOverlapped, NULL);

Кроме того, инициализация OVERLAPPED при использовании WSARecv() аналогична инициализации WSAOVERLAPPED?


person Community    schedule 05.03.2015    source источник
comment
Показанный вами код не работает. Буфер данных и OVERLAPPED должны быть действительными до тех пор, пока перекрывающаяся отправка не завершится и завершение не будет извлечено из IOCP. ТОЛЬКО WSABUF может быть основан на стеке и существовать только во время вызова WSASend() API.   -  person Len Holgate    schedule 06.03.2015
comment
@Len Holgate Итак, buffer и wsaOverlapped должны быть созданы в куче?   -  person    schedule 06.03.2015
comment
Да. В идеале с каким-то распределителем пула, который позволяет вам повторно использовать их, а не прямо в куче.   -  person Len Holgate    schedule 06.03.2015


Ответы (2)


   memset(&wsaOverlapped, 0, sizeof(wsaOverlapped));

Или явно установить все значения равными нулю.

person Len Holgate    schedule 06.03.2015

Структура WSAOVERLAPPED регулируется те же правила, что и в структуре OVERLAPPED, т. е.

Любые неиспользуемые элементы этой структуры всегда должны быть инициализированы нулем, прежде чем структура будет использоваться в вызове функции. В противном случае функция может завершиться ошибкой и вернуть ERROR_INVALID_PARAMETER.

person Harry Johnston    schedule 05.03.2015
comment
Но должен ли я инициализировать любой член WSAOVERLAPPED или OVERLAPPED перед передачей их в WSASend() или WSARecv()? - person ; 05.03.2015
comment
Конечно. Если вы их используете, вы должны инициализировать их соответствующим значением, например, установив для hEvent действительный дескриптор события; если вы их не используете, вы должны инициализировать их до нуля. - person Harry Johnston; 05.03.2015
comment
Если я не хочу использовать события и хочу получать уведомления только через пакеты завершения, должен ли я установить WSAOVERLAPPED.hEvent в NULL или можно вообще не инициализировать его? Кроме того, как насчет других участников, они используются мной или системой? - person ; 05.03.2015
comment
@user4592590: Если вы действительно прочитали WSAOVERLAPPED, WSASend() и WSARecv(), они отвечают на hEvent вопрос. В двух словах, если вы выполняете перекрывающуюся отправку/чтение без IOCP, hEvent должен быть допустимым объектом события или NULL. В противном случае с IOCP вы устанавливаете hEvent на все, что хотите, оно передается как есть обработчику IOCP как данные, определенные пользователем. - person Remy Lebeau; 05.03.2015
comment
@Remy Lebeau Я использую IOCP, но в то же время я назначил WSAOVERLAPPED.hEvent допустимому экземпляру события и ждал его. Что произошло, так это то, что я смог успешно дождаться завершения WSASend(), и как же это могут быть данные, определенные пользователем? Я имею в виду, не увидит ли система, что WSAOVERLAPPED.hEvent не является NULL, и не обработает ли это как действительный экземпляр события? - person ; 05.03.2015
comment
@ user4592590: По-видимому, значение hEvent зависит от значения параметра lpCompletionRoutine для WSASend()/WSARecv(), а не от того, связан ли сокет с IOCP или нет. Если вы установите lpCompletionRoutine в NULL, вы должны установить hEvent в действительный объект события или NULL. Если не NULL, о событии будет сообщено, когда ввод-вывод завершится, и IOCP также получит пакет завершения. - person Remy Lebeau; 05.03.2015
comment
В конкретном случае WSASend и WSARecv hEvent — это единственная часть структуры, для которой может потребоваться установить значение, отличное от нуля. - person Harry Johnston; 05.03.2015