我用的是TCP协议,服务端创建listen socket.
m_socListener = WSASocket(
AF_INET, 
SOCK_STREAM, 
0, 
NULL, 
0, 
WSA_FLAG_OVERLAPPED
);我把客户端连接的socket 关联到完成端口之后,另外开启一个线程等待客户端的数据,
while(1)
{
BOOL bIORet = GetQueuedCompletionStatus(
m_hCompletionPort,
&dwIoSize, 
(LPDWORD) &lpClientContext, 
&lpOverlapped, 
INFINITE);
   if (!bIORet)
{
clear_err_socket(lpClientContext);
}}可是再客户端发送数据之后,GetQueuedCompletionStatus()函数没有唤醒,
或者说GetQueuedCompletionStatus()函数没有任何反映,
就是客户端再关闭时候调用
shutdown(clientSocket);
也不会收到任何消息。
请指教。可以肯定的是我已经关联到完成端口了,而且客户端显示发送数据成功。
也就是数据已经到达服务器了,

解决方案 »

  1.   

    在接受客户端连接后,要调用 Receive,或先 POST 一个消息手工激活。
    等 Receive 到数据后 GetQueuedCompletionStatus() 就唤醒了。
      

  2.   

    DWORD CALLBACK AcceptThreadProc(LPVOID pvArg)
    {
         SOCKET sock;     ...     while(true)
         {
              sock = accept(...);          ...          PostQueuedCompletionStatus(...);
         }     return 0;
    }DWORD CALLBACK ThreadPoolProc(LPVOID pvArg)
    {
         BOOL bRet;
         
         ...     while(true)
         {
              bRet = GetQueuedCompletionStatus(...);          ...          WSARecv(...)          ...
         }     return 0;
    }
      

  3.   

    在接受客户端连接后,要调用 Receive,或先 POST 一个消息手工激活。
    等 Receive 到数据后 GetQueuedCompletionStatus() 就唤醒了。已经激活了
    而且能正常处理手工  POST 的消息。
    但是就是不响应网络的消息,。
    郁闷。
      

  4.   

    将你的 receive 部分贴上来看看。
      

  5.   

    首先socket要和completion port绑定
    而后completion要和thread中的 GetQueuedCompletionStatus确定了吗?
      

  6.   

    OVERLAPPEDPLUS * pOverlap = new OVERLAPPEDPLUS(IORead);
    ULONG ulFlags = MSG_PARTIAL;UINT nRetVal = WSARecv(
    m_Socket,
    &m_wsaInBuffer,
    1,
    &dwIoSize,
    &ulFlags,
    &pOverlap->m_ol,
    NULL);if ( nRetVal == SOCKET_ERROR && WSAGetLastError() != WSA_IO_PENDING)
    {
    // error.
    return false;
    }
      

  7.   

    可能我表达的不是很清楚:
    以下的我 认为时问题的关键,望各位帮忙看看时怎么回事。在accept 完成之后
    手工  GetQueuedCompletionStatus()的消息。
    完成端口可以正常接受到消息,
    可是就是不响应网络的消息,。
    郁闷。
      

  8.   

    // 以下是listen线程:
    DWORD WINAPI
    AcceptThread(LPVOID lParam)
    {
    while(1)
    {
    socClient = WSAAccept(
    m_socListener, 
    NULL,
    NULL, NULL, 0);
    if ( socClient==INVALID_SOCKET )
    {
    break;
    }
    if ( CreateIoCompletionPort(
    (HANDLE)socClient,
    m_hCompletionPort,
    (DWORD)pContext,
    0) != m_hCompletionPort )
    {
    break;
    } ClientContextPtr pContext = new ClientContext();
    pContext->socClient;

    m_pContextList->Add(pContext);
    OVERLAPPEDPLUS *pOverlap = new OVERLAPPEDPLUS(IOInitialize);

    //这个消息GetQueuedCompletionStatus()正常接受到了。
    //而且我观察GetQueuedCompletionStatus()调用得到的 pContext结构没有任何问题。
    BOOL bSuccess = PostQueuedCompletionStatus
    (
    m_hCompletionPort, 
    0,
    (DWORD) pContext, 
    &pOverlap->m_ol
    );
    if ( (!bSuccess && GetLastError() != ERROR_IO_PENDING) )
    {
    m_pContextList->Remove(pContext);
    }
    }
    }可要是客户端发送的网络消息GetQueuedCompletionStatus()
    函数没有任何反应,
    甚至客户端调用shutdown(clientSocket )也一样。
      

  9.   


     m_socListener = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
    改为
     m_socListener = socket(AF_INET, SOCK_STREAM, 0);
      

  10.   

    你没有激发IOCP
    在while循环里加上 ::WSAREcv();
    来触发完成端口
      

  11.   

    如果get函数可以被正常阻塞的话,那问题应该出在wsarecv未被正常执行。
      

  12.   

    在WSARecv()之后,判断错误是不是WSA_IO_PENDING.如果不是,就是你的参数有问题