Hey ... J'ai créé un petit serveur de test en utilisant les ports d'achèvement d'E/S et winsock. Je peux connecter et associer avec succès une poignée de socket au port d'achèvement. Mais je ne pas savoir comment passer des structures de données définies par l'utilisateur dans le fil wroker ...Comment passer des données définies par l'utilisateur à un thread de travail en utilisant le protocole IOCP?
Ce qui a essayé à ce jour Ive a été le passage d'une structure utilisateur comme (ULONG_PTR)&structure as
l'achèvement clé dans l'association d'appel de CreateIoCompletionPort()
Mais cela n'a pas fonctionné.
Maintenant, j'ai essayé de définir ma propre structure OVERLAPPED et d'utiliser CONTAINING_RECORD() comme décrit ici http://msdn.microsoft.com/en-us/magazine/cc302334.aspx et http://msdn.microsoft.com/en-us/magazine/bb985148.aspx. Mais ça ne marche pas aussi. Donc, ma question est: Comment puis-je transmettre des données au thread de travail en utilisant WSARecv(), GetQueuedCompletionStatus() et le paquet Achèvement ou le OVERLAPPED-strucutre?
EDIT: Comment puis-je transmettre avec succès "per-connection-data"? ... Il semble que j'ai eu l'art de le faire (comme expliqué dans les deux liens ci-dessus) faux.
va Voici mon code: (Oui, son laid et son seul code TEST)
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, merci pour l'aide. Pouvez-vous m'aider avec ma deuxième question aussi? Comment puis-je envoyer correctement ce "per-connection-data" sur la structure OVERLAPPED? ... Comme mentionné dans mon OP, je n'ai pas réussi à le faire fonctionner avec le CONTENU_RECORD() - Macro – Incubbus
Pourquoi ne déplacez-vous pas le ' OVERLAPPED sur; 'membre au sommet de la' struct' et juste jeter le pointeur sur 'helper *'? –
Même si cela fonctionne, cela me semble erroné - être dépendant de l'ordre des structures dans les structures - ... – Incubbus