- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
编辑:我猜问题是我必须将容器中的 OVERLAPPED 或 WSAOVERLAPPED 与我的完成端口相关联。对吗?
当有人连接到我的服务器时,我可以获得 IO 完成。然后,我在新套接字上使用 CreateIoCompletionPort,并使用原来使用的完成端口。但是当他们向我发送数据时,它并没有被触发。虽然,如果其他人连接,它仍然会被触发。我的问题是,为什么会发生这种情况?我还确保 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;
}
最佳答案
我不想再这样做了,但我是对的,你必须使用 WSARECV 将套接字置于一种新模式(很像 acceptex):我不知道这个,在 MSDN 上也不是很清楚,还有一个我正在寻找学习 IOCP 的资源,没有谈论它。希望这对某人有帮助:/
WSABUF wbuf;
DWORD bytes, flags;
wbuf.buf = cicc2->client_buff;
wbuf.len = cicc2->client_len;
flags = 0;
int rr = WSARecv ( cicc2->client_socket , &wbuf , 1 , &bytes , &flags , &cicc2->ol , NULL );
if (rr == FALSE) {
if (WSAGetLastError() != WSA_IO_PENDING) {
printf("PostRecv: WSARecv* failed: %d\n", WSAGetLastError());
closesocket(cicc2->client_socket);
cic->deleteNode ( cicc2->client_socket , cic );
}
fprintf(stderr, "PostRecv: WSARecv* failed: %d\n", GetLastError());
}
关于新套接字上的 C++ CreateIoCompletionPort,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11557869/
编辑:我猜问题是我必须将容器中的 OVERLAPPED 或 WSAOVERLAPPED 与我的完成端口相关联。对吗? 当有人连接到我的服务器时,我可以获得 IO 完成。然后,我在新套接字上使用 Cre
关于 MSDN page for CreateIoCompletionPort这个函数的最后一个参数有一个非常简短的描述: NumberOfConcurrentThreads [in] The max
查看 MSDN documentation对于 CreateIoCompletionPort 我们读到: NumberOfConcurrentThreads [in] The maximum numb
当使用 CreateIoCompletionPort() 将 SOCKET 与完成端口相关联时,我可以将直接值(即不是指针)传递给 CompletionKey 参数,还是只传递一个指针? 我想做的是传
我正在向我的(基于 Qt 的)应用程序添加功能,以递归地监视我的 Windows 系统上的任意文件夹的任何事件(这是 Qt 变体 QFileSystemWatcher 所缺少的)。使用 CreatFi
背景:如本文所述,Designing Applications for High Performance : Consider using PostQueueCompletionStatus rath
我是一名优秀的程序员,十分优秀!