本帖最后由 txz_yshb 于 2011-09-29 17:23:51 编辑

解决方案 »

  1.   

    我觉得你在case Accept:
    中的ContextKey*  pCntxNew = new ContextKey(pCntx->m_sock);这步有问题,多余。因为GetQueuedCompletionStatus(g_hCP, &dwBytes, (DWORD*)&pCntx, &lpOverlapped, INFINITE);
    里面lpOverlapped已经包含了accept进来的所有信息了,所以你第一次投递 WSARecv消息的时候可以直接用lpOverlapped里面的socket,你只是要对当前接受的socket投递接受信息,没必要再new,  而你在开始在for循环中AcceptEx前的pCntx = new ContextKey(WSASocket(AF_INET, SOCK_STREAM , IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED));的pCntx最好用数组保存起来,以后每次有rec信息时只需比对lpOverlapped->套接字与pCntx结构体中的套接字是否相等,就可以了
      

  2.   

    因为我省略了部分代码case Accept:
    {
    setsockopt(pCntx->m_sock, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT, (char*)&sockListen, sizeof(SOCKET)); ContextKey*  pCntxNew = new ContextKey(pCntx->m_sock);

    CreateIoCompletionPort((HANDLE)pCntxNew->m_sock, g_hCP, (DWORD)pCntxNew, 0
    WSARecv(pCntxNew->m_sock, &pCntxNew->m_wsaBuf, 1, NULL, &pCntxNew->m_dwFlag, pCntxNew, NULL);

    pCntx->ReInit( WSASocket(AF_INET, SOCK_STREAM , IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED));//重新初始化
    if (AcceptEx(sockListen, pCntx->m_sock, pCntx->m_wsaBuf.buf, 0, sizeof(SOCKADDR)+16, sizeof(SOCKADDR)+16,
    &pCntx->m_dwBytes, pCntx) == FALSE && WSAGetLastError() != ERROR_IO_PENDING)
    return 0;
    break;
    } 所以这里一定要new一个ContextKey这里让人最不能理解的是,前面我只投递一个AcceptEx的时候没有问题,投递多个的时候第一个WSARecv就出错
      

  3.   

    那我感觉你程序的逻辑有问题,你是想让这个accep了之后,重新再投递一个accept请求?那你之前的for循环的作用就没发挥出来啊,最好把你ContextKey的代码也贴下
      

  4.   

    我觉得这种IOCP模型,应该在开始的时候应该定下来最多的Accept,然后启动它们接受客户端的请求,当客户端连接直至客户端完全退出之后再重新去Accept;