Как получить буфер в CompletionROUTINE помимо вызова WSARecvFrom?

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

Я заметил, что вы передаете PWSAOVERLAPPED WSARecvFrom, и он содержит LPVOID Pointer член. Могу ли я создать свою собственную структуру пользовательских данных, содержащую ссылку на буфер, и передать ее как указатель внутри этого Pointer члена PWSAOVERLAPPED?

Я подумал, что это немного избыточно, хотя полученные байты были доступны в двух местах:

lpNumberOfBytesRecvd аргумент WSARecvFrom и параметр cbTransferred lpCompletionRoutine.

Пример моей текущей процедуры завершения:

void CALLBACK CompletionROUTINE(
  DWORD dwError, 
  DWORD cbTransferred, 
  LPWSAOVERLAPPED lpOverlapped, 
  DWORD dwFlags
) {
    UNREFERENCED_PARAMETER(dwError);
    UNREFERENCED_PARAMETER(lpOverlapped);
    UNREFERENCED_PARAMETER(dwFlags);

    /* Best way to get the bytes read here? */
    Printf(L"Recieved %d bytes\n", cbTransferred);
}

и мой звонок WSARecvFrom:

iResult = WSARecvFrom(
    listenSocket, 
    &wsaBuffer, 
    1, 
    &dwBytesRecieved, 
    &dwFlags, 
    (PSOCKADDR)&sender, 
    &senderAddrSize, 
    &wsaOverlapped,
    CompletionROUTINE
);

person jacob    schedule 07.06.2018    source источник
comment
Обратите внимание, что механизм перекрытия используется для других операций ввода-вывода и протоколов. Это может привести к некоторому перекрытию, и это один из примеров. Лучше дважды, чем никогда :)   -  person Martin James    schedule 07.06.2018
comment
Я использую поле hEvent для передачи указателя / экземпляра объекта контекста. Этот экземпляр включает буфер / ы и перекрывающийся блок.   -  person Martin James    schedule 07.06.2018
comment
@MartinJames Как вы собираетесь ждать результатов? Вы не можете использовать WSAWaitForMultipleEvents, потому что указываете собственное событие, которое не является допустимым дескриптором.   -  person jacob    schedule 08.06.2018
comment
С вызовом цикла WaitForSingleObjectEx для семафора с 'bAlertable set true ... Если WFSO возвращается с' WAIT_IO_COMPLETION ', я игнорирую его, и любые требуемые действия происходят в подпрограмме завершения. Если «WAIT_OBJECT_0», это означает, что некоторый экземпляр объекта запроса ввода-вывода ожидает в очереди, и он должен быть исключен из очереди и обработан.   -  person Martin James    schedule 09.06.2018


Ответы (1)


Из документации структуры _1:

hEvent Тип: HANDLE Если перекрывающаяся операция ввода-вывода выполняется без подпрограммы завершения ввода-вывода (параметр операции lpCompletionRoutine имеет значение null), то этот параметр должен либо содержать допустимый дескриптор объекта WSAEVENT, либо иметь значение null. Если параметр lpCompletionRoutine вызова не равен нулю, приложения могут использовать этот параметр по мере необходимости.

Итак, поскольку я предоставляю параметр lpCompletionRoutine, я могу использовать WSAEvent как указатель на мои пользовательские данные.

Спасибо комментатору, который привел меня к этому выводу.

person jacob    schedule 08.06.2018