我正在編寫使用IO完成端口的多線程客戶端。多線程IOCP客戶端問題
我創建並連接了具有WSA_FLAG_OVERLAPPED屬性集的套接字。
if ((m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
throw std::exception("Failed to create socket.");
}
if (WSAConnectByName(m_socket, L"server.com", L"80", &localAddressLength, reinterpret_cast<sockaddr*>(&localAddress), &remoteAddressLength, &remoteAddress, NULL, NULL) == FALSE)
{
throw std::exception("Failed to connect.");
}
我的IO完成端口與插座關聯。
if ((m_hIOCP = CreateIoCompletionPort(reinterpret_cast<HANDLE>(m_socket), m_hIOCP, NULL, 8)) == NULL)
{
throw std::exception("Failed to create IOCP object.");
}
在我嘗試通過套接字發送一些數據之前,所有內容似乎都很順利。
SocketData* socketData = new SocketData;
socketData->hEvent = 0;
DWORD bytesSent = 0;
if (WSASend(m_socket, socketData->SetBuffer(socketData->GenerateLoginRequestHeader()), 1, &bytesSent, NULL, reinterpret_cast<OVERLAPPED*>(socketData), NULL) == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
{
throw std::exception("Failed to send data.");
}
WSASend不會返回SOCKET_ERROR,而是將上一個錯誤設置爲WSA_IO_PENDING,WSASend會立即返回。
我需要IO掛起,並完成處理我的線程函數,這也是我的工作線程。
unsigned int __stdcall MyClass::WorkerThread(void* lpThis)
{
}
我之前已經這樣做了,但我不知道什麼是在這種情況下會錯了,我會非常感謝幫助我解決這個問題的任何努力。
那麼問題是,WSARecv立即返回,而不是張貼到IOCP隊列。返回的最後一個錯誤是0,因爲它應該是ERROR_IO_PENDING。我通過使用ConnectEx而不是WSAConnect解決了問題。感謝您的回覆:) – Carl 2010-06-14 10:42:31
我的觀點是,WSARecv CAN LEGALLY返回0,IT STILL以與返回ERROR_IO_PENDING時相同的方式發佈IO完成,除非您通過調用SetFleCompletionNotificationModes()來調整它的工作方式你告訴它不要在它返回成功時發佈一個IO完成......如果你已經用適當的標誌調用SetFileCompletionNotificationModes(),你只需要有成功返回的特殊情況代碼。 – 2010-06-14 12:51:16
啊,我不知道。好的,謝謝你! =] – Carl 2010-06-14 20:46:04