• Advertisement
Sign in to follow this  

Failed IOCP attempt

This topic is 2127 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello,

I've been reading through posts and noticed some people suggest to use IOCP on server to handle a lot packets more efficiently. I've used http://askldjd.wordp...r-1-2-released/ as some kind of reference and tried to initialize basic IOCP and get it it working, however I get WSA_INVALID_PARAMETER error in GetQueuedCompletionStatus inside worker thread when client attempts to connect.

Here's my code:

void main() {
WSADATA wsaData;
int numThreads = 1;
vector<HANDLE> threads;

// InitializeWinsock();
WSAStartup(MAKEWORD(2,2), &wsaData);

// InitializeIocp();
m_ioCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, numThreads);
if(m_ioCompletionPort == NULL)
cout << "CreateIoCompletionPort() => " << WSAGetLastError() << endl;

// InitializeThreadPool();
threads.reserve(numThreads);
for(auto i = 0; i < numThreads; ++i)
threads.push_back(CreateThread(0, 0, (LPTHREAD_START_ROUTINE)&WorkerThread, m_ioCompletionPort, 0, 0));

// InitializeSocket();
InitializeSocket(ADDR_ANY, 50000);

// InitializeAcceptEvent();
m_socket = CreateOverlappedSocket();
PostAccept();

// client (?)
SOCKET client = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
sockaddr_in address = { };
address.sin_family = AF_INET;
address.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
address.sin_port = htons(50000);
auto result = WSAConnect(client, (sockaddr*)&address, sizeof(address), 0, 0, 0, 0);
if(result == SOCKET_ERROR)
cout << "WSAConnect() => " << WSAGetLastError() << endl;

system("pause");
}

void WorkerThread(HANDLE m_ioCompletionPort) {
for(;;) {
void *key = nullptr;
OVERLAPPED *overlapped = nullptr;
DWORD bytesTransferred = 0;

BOOL completionStatus = GetQueuedCompletionStatus(m_ioCompletionPort, &bytesTransferred, (LPDWORD)&key, &overlapped, INFINITE);

if(completionStatus == FALSE) {
cout << "GetQueuedCompletionStatus() => " << WSAGetLastError() << endl;
continue;
}

if(key == NULL) {
cout << "GetQueuedCompletionStatus() => " << WSAGetLastError() << endl;
break;
}
}
}

SOCKET CreateOverlappedSocket() {
return WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
}

LPFN_ACCEPTEX LoadAcceptEx(SOCKET s) {
LPFN_ACCEPTEX lpfnAcceptEx = NULL;
DWORD dwBytes = 0;
GUID GuidAcceptEx = WSAID_ACCEPTEX;

auto result = WSAIoctl(s, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidAcceptEx, sizeof(GuidAcceptEx), &lpfnAcceptEx, sizeof(lpfnAcceptEx), &dwBytes, NULL, NULL);
if(result == SOCKET_ERROR) {
cout << "WSAIoctl() => " << WSAGetLastError() << endl;
return nullptr;
}

return lpfnAcceptEx;
}

void AssociateDevice(HANDLE h) {
auto result = CreateIoCompletionPort(h, m_ioCompletionPort, 0, 0);
if(result == NULL) {
cout << "CreateIoCompletionPort() => " << WSAGetLastError() << endl;
return;
}
}

void InitializeSocket(uint32 addressToListenOn, uint16 portNumber) {
m_listenSocket = CreateOverlappedSocket();

sockaddr_in serverAddress = { };
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = addressToListenOn;
serverAddress.sin_port = htons(portNumber);

auto result = bind(m_listenSocket, (sockaddr*)&serverAddress, sizeof(serverAddress));
if(result == -1) {
cout << "bind() => " << WSAGetLastError() << endl;
return;
}

result = listen(m_listenSocket, SOMAXCONN);
if(result == SOCKET_ERROR) {
cout << "listen() => " << WSAGetLastError() << endl;
return;
}

m_acceptExFn = LoadAcceptEx(m_listenSocket);
if(m_acceptExFn == FALSE) {
cout << "LoadAcceptEx() => " << WSAGetLastError() << endl;
return;
}

AssociateDevice((HANDLE)m_listenSocket);
}

void PostAccept() {
DWORD bytesReceived_ = 0;
DWORD addressSize = sizeof(sockaddr_in) + 16;
auto result = m_acceptExFn(m_listenSocket, m_socket, m_data, 0, addressSize, addressSize, &bytesReceived_, 0/*&m_acceptContext*/);
if(result == 0) {
if(WSAGetLastError() != WSA_IO_PENDING)
cout << "m_acceptExFn() => " << WSAGetLastError() << endl;
return;
}

result = PostQueuedCompletionStatus(m_ioCompletionPort, 0, 0, 0/*&m_acceptContext*/);
if(result == 0) {
cout << "PostQueuedCompletionStatus() => " << WSAGetLastError() << endl;
return;
}
}

Share this post


Link to post
Share on other sites
Advertisement
If you want to get up to speed on IOCP in general you might find my free IOCP client/server code of some use, it's pretty old now but it works well and the articles that I wrote for CodeProject explain what's going on.

You can download the code from here and there are links to the articles that explain it.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement