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