1
编辑:我猜测问题是我必须将容器中的OVERLAPPED或WSAOVERLAPPED与我的完成端口相关联。那是对的吗?C++ CreateIoCompletionPort在新插座上
当有人连接到我的服务器时,我可以获得IO完成。然后,我在新套接字上使用CreateIoCompletionPort,并使用原始的completionport。但是当他们向我发送数据时,它并没有出现。尽管如果有人连接,它仍然会出现。我的问题是,为什么会发生这种情况?我也确保CreateIoCompletionPort返回与原始相同的句柄。是什么赋予了?
编辑:
DWORD WINAPI worker_thread(LPVOID lpParam) {
client_information_class *cicc = NULL;
HANDLE CompletionPort = (HANDLE)lpParam;
ULONG_PTR Key;
DWORD BytesTransfered;
OVERLAPPED *lpOverlapped = NULL;
DWORD error = NULL;
while(1) {
error = GetQueuedCompletionStatus(CompletionPort, &BytesTransfered, (PULONG_PTR)&Key, &lpOverlapped, 0);
cicc = CONTAINING_RECORD (lpOverlapped, client_information_class, ol);
if (error == TRUE) {
cout << endl << "IO TRIGGERED" << endl;
switch (cicc->operation) {
/*#define OP_ACCEPT 0
#define OP_READ 1
#define OP_WRITE 2*/
case 0:{
if (check_auth_progress (cicc->client_socket , cicc->client_buff , BytesTransfered)) {
cout << "Client " << cicc->client_socket << " connected." << endl;
client_information_class *k = NULL;
SOCKADDR_STORAGE *LocalSockaddr=NULL, *RemoteSockaddr=NULL;
int LocalSockaddrLen,RemoteSockaddrLen;
k = (client_information_class *)Key;
k->lpfnGetAcceptExSockaddrs(
cicc->client_buff,
cicc->client_len - ((sizeof(SOCKADDR_STORAGE) + 16) * 2),
sizeof(SOCKADDR_STORAGE) + 16,
sizeof(SOCKADDR_STORAGE) + 16,
(SOCKADDR **)&cicc->LocalSockaddr,
&cicc->LocalSockaddrLen,
(SOCKADDR **)&cicc->RemoteSockaddr,
&cicc->RemoteSockaddrLen
);
client_information_class *cicc2 = NULL;
cicc2 = (client_information_class *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(client_information_class) + (sizeof(BYTE) * 4096));
if (cicc2 == NULL) {
fprintf(stderr, "Out of memory!\n");
}
cicc2->client_socket = cicc->client_socket;
cicc2->client_socketaddr_in = cicc->client_socketaddr_in;
cicc2->LocalSockaddr = cicc->LocalSockaddr;
cicc2->LocalSockaddrLen = cicc->LocalSockaddrLen;
cicc2->RemoteSockaddr = cicc->RemoteSockaddr;
cicc2->RemoteSockaddrLen = cicc->RemoteSockaddrLen;
HANDLE hrc = CreateIoCompletionPort((HANDLE)cicc2->client_socket, CompletionPort, (ULONG_PTR)cic, 0);
if (hrc == NULL) {
fprintf(stderr, "CompletionThread: CreateIoCompletionPort failed: %d\n", GetLastError());
return 0;
} else {
fprintf(stderr, "CompletionThread: CreateIoCompletionPort: %d\n", hrc);
}
cic->deleteNode (cicc->client_socket , cic);
cic->addNode (cicc2);
} else {
cout << endl << "Something Happened ... " << endl;
}
}break;
case 1:{
if (ParsePacket (cicc->client_socket , data)) {
cout << "Client " << cicc->client_socket << " connected." << endl;
} else {
cout << endl << "Something Happened ... " << endl;
}
}break;
default:{
cout << endl << "Didnt catch that operation ... " << cicc->operation << endl;
}break;
}
} else if (error == FALSE && &lpOverlapped == NULL) {
// no packet was dequed...
fprintf(stderr, "[error == FALSE && &lpOverlapped == NULL] CompletionThread: GetQueuedCompletionStatus failed: %d [0x%x]\n", GetLastError(), &lpOverlapped->Internal);
} else if (error == FALSE && &lpOverlapped != NULL) {
if((DWORD)&lpOverlapped->Internal == 0x0) { // a timeout...
} else {
fprintf(stderr, "[error == FALSE && &lpOverlapped != NULL] CompletionThread: GetQueuedCompletionStatus failed: %d [0x%x]\n", GetLastError(), &lpOverlapped->Internal);
}
}
}
ExitThread(0);
return 0;
}
你打电话只能在被动监听套接字'CreateIoCompletionPort',或在新接受的套接字呢?虽然我没有使用完成端口的经验,但通常您必须手动配置已接受的套接字,但它们不会从套接字“继承”任何东西。 – 2012-07-19 09:38:33
我只在新的套接字上调用它。我还分配了一个新的空间来创建一个新的套接字,并将接受的套接字复制到新的套接字中,并将completionport放置在那里,没有任何反应。 – User 2012-07-19 09:42:41
你能否告诉我们相关的代码?如果你向我们展示你所做的事情,帮助你将会简单得多。 – 2012-07-19 10:03:25