Я читаю об IOCP через эту статью
http://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancediomethod5i.html
Эта первая функция WSARecv, которую он использовал с 0 lpNumberOfBytesRecvd
инициировать завершение портов
if (WSARecv(Accept, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags, &(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
{
if (WSAGetLastError() != ERROR_IO_PENDING)
{
printf("WSARecv() failed with error %d\n", WSAGetLastError());
return 1;
}
}
else
printf("WSARecv() is OK!\n");
}
Теперь на рабочих потоках функция, где приложение получает IO сообщение
это проверяет параметр lpNumberOfBytes
из GetQueuedCompletionStatus
для 0 также, а затем он закрывает соединение, если это
// First check to see if an error has occurred on the socket and if so
// then close the socket and cleanup the SOCKET_INFORMATION structure
// associated with the socket
if (BytesTransferred == 0)
Когда я попробовал это, первое сообщение IOCP отправило функцию GetQueuedCompletionStatus
он всегда возвращает 0 в lpNumberOfBytes
параметр, потому что первый WSARecv
вызов был вызван с lpNumberOfBytesRecvd
установить на ноль
Я пытался реализовать этот код, и у меня возникли проблемы, чтобы заставить код работать, если я не решу не использовать NULL в этом параметре
в первом звонке WSARecv
таким образом GetQueuedCompletionStatus
функция, возвращающая значение 0 в lpNumberOfBytes
может использоваться как в случае получения всех данных.
MSDN говорит использовать NULL
lpNumberOfBytesRecvd [out]
Указатель на количество в байтах данных, полученных этим вызовом, если
Операция приема завершается немедленно.Используйте NULL для этого параметра, если параметр lpOverlapped не равен NULL
чтобы избежать потенциально ошибочных результатов. Этот параметр может быть НЕДЕЙСТВИТЕЛЕН
только если параметр lpOverlapped не равен NULL.
Код не работает хорошо, если я позвоню WSARecv
снова (внутри функции рабочих потоков) и все данные были получены, это вызывает GetQueuedCompletionStatus
функция для немедленного возврата без ожидания, даже если используется INFINITE и рабочие потоки входят в бесконечный цикл. Ошибки не возвращаются GetQueuedCompletionStatus
Функция это просто действует так, как будто есть больше данных, но их нет.
WSARecv
с каким значением нужно инициировать размер буфера?
также я должен использовать неблокирующий сокет? или просто обычные блокирующие сокеты, так как я использую отдельный поток для приема соединений, поэтому я думаю, что это нормально, потому что это не замораживает мой графический интерфейс.
Задача ещё не решена.
Других решений пока нет …