Hey ... Ich habe einen kleinen Testserver mit I/O Completion Ports und Winsock erstellt. Ich kann erfolgreich eine Socket-Handle mit dem Completion-Port verbinden und zuordnen. dont Aber ich weiß, wie benutzerdefinierte Datenstrukturen in den wroker Faden ...Wie können benutzerdefinierte Daten mithilfe von IOCP an einen Worker-Thread übergeben werden?
Was Ive wurde versucht, so weit passieren eine benutzer Struktur als (ULONG_PTR)&structure as
Bestehen der Fertigstellung Key im Verein-Aufruf von CreateIoCompletionPort()
Aber das hat nicht funktioniert.
Jetzt habe ich versucht, meine eigene OVERLAPPED-Struktur zu definieren und CONTAINING_RECORD() zu verwenden, wie hier beschrieben http://msdn.microsoft.com/en-us/magazine/cc302334.aspx und http://msdn.microsoft.com/en-us/magazine/bb985148.aspx. Aber das funktioniert auch nicht. (Ich bekomme freaky Werte für den Inhalt von pHelper)
Also meine Frage ist: Wie kann ich Daten übergeben, die Worker-Thread mit WSARecv(), GetQueuedCompletionStatus() und das Completion-Paket oder die OVERLAPPED-Struktur?
EDIT: Wie kann ich "per-connection-data" erfolgreich übertragen? ... Es scheint, als ob ich die Kunst, es zu tun (wie in den beiden obigen Links erklärt) falsch gemacht habe.
geht hier mein Code: (Ja, es ist hässlich und es ist nur TEST-Code)
struct helper
{
SOCKET m_sock;
unsigned int m_key;
OVERLAPPED over;
};
///////
SOCKET newSock = INVALID_SOCKET;
WSABUF wsabuffer;
char cbuf[250];
wsabuffer.buf = cbuf;
wsabuffer.len = 250;
DWORD flags, bytesrecvd;
while(true)
{
newSock = accept(AcceptorSock, NULL, NULL);
if(newSock == INVALID_SOCKET)
ErrorAbort("could not accept a connection");
//associate socket with the CP
if(CreateIoCompletionPort((HANDLE)newSock, hCompletionPort, 3,0) != hCompletionPort)
ErrorAbort("Wrong port associated with the connection");
else
cout << "New Connection made and associated\n";
helper* pHelper = new helper;
pHelper->m_key = 3;
pHelper->m_sock = newSock;
memset(&(pHelper->over), 0, sizeof(OVERLAPPED));
flags = 0;
bytesrecvd = 0;
if(WSARecv(newSock, &wsabuffer, 1, NULL, &flags, (OVERLAPPED*)pHelper, NULL) != 0)
{
if(WSAGetLastError() != WSA_IO_PENDING)
ErrorAbort("WSARecv didnt work");
}
}
//Cleanup
CloseHandle(hCompletionPort);
cin.get();
return 0;
}
DWORD WINAPI ThreadProc(HANDLE h)
{
DWORD dwNumberOfBytes = 0;
OVERLAPPED* pOver = nullptr;
helper* pHelper = nullptr;
WSABUF RecvBuf;
char cBuffer[250];
RecvBuf.buf = cBuffer;
RecvBuf.len = 250;
DWORD dwRecvBytes = 0;
DWORD dwFlags = 0;
ULONG_PTR Key = 0;
GetQueuedCompletionStatus(h, &dwNumberOfBytes, &Key, &pOver, INFINITE);
//Extract helper
pHelper = (helper*)CONTAINING_RECORD(pOver, helper, over);
cout << "Received Overlapped item" << endl;
if(WSARecv(pHelper->m_sock, &RecvBuf, 1, &dwRecvBytes, &dwFlags, pOver, NULL) != 0)
cout << "Could not receive data\n";
else
cout << "Data Received: " << RecvBuf.buf << endl;
ExitThread(0);
}
Hey, Danke für die Hilfe. Können Sie mir auch bei meiner zweiten Frage helfen? Wie kann ich diese "per-connection-data" korrekt über die OVERLAPPED-Struktur senden? ... Wie in meinem OP erwähnt, habe ich es nicht richtig mit dem CONTAINING_RECORD() - Macro – Incubbus
Warum bewegst du den '' nicht OVERLAPPED over; 'Mitglied an die Spitze der' struct' und dann einfach den Zeiger auf 'helper *'? –
Auch wenn es funktioniert, scheint mir das irgendwie falsch - abhängig von der Reihenfolge der Strukturen innerhalb von Strukturen - ... – Incubbus