输出结果如下:
Start a thread.
Server is running..........0 times
accept a event!
accept a connect!
accept connect but no data!
post a read data!
Server is running..........1 times也就是只有接到连接,没有受到发送的数据,哪里错了呢?
Server is running 那是检测连接的输出,判断是否有没有发送数据的恶意连接。DWORD WINAPI IOCPServer::CompletionRoutine(LPVOID lpParam)
{
IOCPServer* lp_this = (IOCPServer*)lpParam;
DWORD dwBytes = 0;
DWORD dwFlags = 0;
HANDLE hRet;
BOOL bRet;
int nRet; PPER_HANDLE_DATA lp_Handle = NULL;
LPWSAOVERLAPPED lp_ol   = NULL;
PPER_IO_DATA lp_IO     = NULL;
PPER_HANDLE_DATA    lp_new_Handle;
while(TRUE)
{
bRet = GetQueuedCompletionStatus(lp_this->m_hCompletion, &dwBytes, (LPDWORD)&lp_Handle, &lp_ol, INFINITE);
cout<<"accept a event!"<<endl;
lp_IO = (PPER_IO_DATA)lp_ol;

if(bRet == FALSE)
{
lp_this->Error("GetQueuedCompletionStatus failed!");
lp_this->m_perHandleList.remove(lp_Handle);
lp_this->m_perIOList.remove(lp_IO);
continue;
}
if(lp_IO == NULL)
{
cout<<"receive a null CIOContext!"<<endl;
continue;
}
if( (lp_IO->operation != IOCP_ACCEPT) && (dwBytes == 0))
{
lp_this->MSG("a user logout");
closesocket(lp_IO->socket);
lp_this->m_perHandleList.remove(lp_Handle);
lp_this->m_perIOList.remove(lp_IO);
lp_this->m_onlineCount--;
continue;
} switch(lp_IO->operation)
{
case IOCP_ACCEPT:
lp_this->MSG("accept a connect!");
lp_this->m_onlineCount++; nRet = setsockopt(lp_IO->socket, SOL_SOCKET, SO_UPDATE_ACCEPT_CONTEXT,
(char*)&lp_this->m_socket, sizeof(lp_this->m_socket));
if(nRet == SOCKET_ERROR)
{
lp_this->Error("update socket fail!");
closesocket(lp_IO->socket);
lp_this->m_perIOList.remove(lp_IO);
continue;
}
lp_new_Handle = (PPER_HANDLE_DATA)::GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA));
if(lp_new_Handle == NULL)
{
lp_this->Error("get a handle fail!");
closesocket(lp_IO->socket);
continue;
}
lp_this->m_perHandleList.push_back(lp_new_Handle);
lp_new_Handle->socket = lp_IO->socket; hRet = CreateIoCompletionPort((HANDLE)lp_IO->socket, lp_this->m_hCompletion,
(DWORD)lp_new_Handle, 0);
if(hRet == NULL)
{
lp_this->Error("link to iocp fail!");
closesocket(lp_IO->socket);
lp_this->m_perHandleList.remove(lp_new_Handle);
lp_this->m_perIOList.remove(lp_IO);
continue;
} //数据处理
if(dwBytes > 0)
{
lp_IO->wsaBuf.len = dwBytes;
lp_this->MSG("read a data!");
lp_IO->operation = IOCP_WRITE;
lp_this->MSG(lp_IO->wsaBuf.buf);
memset(&lp_IO->ol, 0, sizeof(lp_IO->ol));

lp_this->MSG("post write data!");
nRet = WSASend(lp_IO->socket, &lp_IO->wsaBuf, 1, &dwBytes, 0, &lp_IO->ol,NULL);
if((nRet == SOCKET_ERROR) && (WSAGetLastError() !=WSA_IO_PENDING))
{
lp_this->Error("WSASend fail!");
closesocket(lp_IO->socket);
lp_this->m_perHandleList.remove(lp_new_Handle);
lp_this->m_perIOList.remove(lp_IO);
}
//continue;
}
else
{
lp_this->MSG("accept connect but no data!");
lp_this->InitIOContext(lp_IO);
lp_IO->operation = IOCP_READ; lp_this->MSG("post a read data!");
dwFlags = 0;
nRet = WSARecv(lp_IO->socket, &lp_IO->wsaBuf, 1, &dwBytes, &dwFlags, &lp_IO->ol, NULL);
if((nRet == SOCKET_ERROR) && (WSAGetLastError() != WSA_IO_PENDING))
{
lp_this->MSG("WSARecv fail!");
closesocket(lp_IO->socket);
lp_this->m_perHandleList.remove(lp_new_Handle);
lp_this->m_perIOList.remove(lp_IO);
}
}
break;
case IOCP_READ:
lp_IO->wsaBuf.len = dwBytes;
lp_this->MSG("read a data!");
lp_IO->operation = IOCP_WRITE;
memset(&lp_IO->ol, 0, sizeof(lp_IO->ol));
lp_this->MSG("post write data!");
nRet = WSASend(lp_IO->socket, &lp_IO->wsaBuf, 1, &dwBytes, 0, &lp_IO->ol,NULL);
if((nRet == SOCKET_ERROR) && (WSAGetLastError() !=WSA_IO_PENDING))
{
lp_this->Error("WSASend fail!");
closesocket(lp_IO->socket);
lp_this->m_perHandleList.remove(lp_new_Handle);
lp_this->m_perIOList.remove(lp_IO);
}
break;
case IOCP_WRITE:
lp_this->MSG("write a data!");
lp_this->InitIOContext(lp_IO);
lp_IO->operation = IOCP_READ;
lp_this->MSG("post a read data!");
dwFlags = 0;
nRet = WSARecv(lp_IO->socket, &lp_IO->wsaBuf, 1, &dwBytes, &dwFlags, &lp_IO->ol, NULL);
if((nRet == SOCKET_ERROR) && (WSAGetLastError() != WSA_IO_PENDING))
{
lp_this->MSG("WSARecv fail!");
closesocket(lp_IO->socket);
lp_this->m_perHandleList.remove(lp_new_Handle);
lp_this->m_perIOList.remove(lp_IO);
}
break;
case IOCP_END:
lp_this->MSG("close a socket!");
closesocket(lp_IO->socket);
lp_this->m_perHandleList.remove(lp_Handle);
lp_this->m_perIOList.remove(lp_IO);
break;
default:
lp_this->MSG("nothing event!");
break;
}
return TRUE;
}
}

解决方案 »

  1.   

    你用的AcceptEx?看一下你的AcceptEx是怎么调用的呢?
      

  2.   

    BOOL IOCPServer::PostAcceptEx()
    {
    int count = 10;
    DWORD dwBytes;
    BOOL bRet; for(int i=0; i<count; i++)
    {
    SOCKET socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED);
    if(socket == INVALID_SOCKET)
    {
    Error("post accpetex failed!");
    continue;
    } PPER_IO_DATA pPerIO = (PPER_IO_DATA)::GlobalAlloc(GPTR, sizeof(PER_IO_DATA));
    InitIOContext(pPerIO);
    pPerIO->socket = socket;
    pPerIO->operation = IOCP_ACCEPT; bRet = lpAcceptEx(m_socket, pPerIO->socket, pPerIO->buf, 0, 
    sizeof(sockaddr_in) + 16,
    sizeof(sockaddr_in) + 16,
    &dwBytes, &pPerIO->ol);
    if((bRet == FALSE) && (WSAGetLastError() != WSA_IO_PENDING))
    {
    Error("post acceptex failed!");
    closesocket(socket);
    }
    m_perIOList.push_back(pPerIO);
    }
    return TRUE;
    }
      

  3.   

    晕,终于找到错误在哪里了,那个CompletionRoutine函数的return TRUE写错了地方,应该在下一个花括号后面,差不多半天功夫就浪费在这上面了。