完成例程如下:
========================
void __stdcall OIOServer::completionRoutine(DWORD dwError,
   DWORD cbTransferred,
   LPWSAOVERLAPPED lpOverlapped,
   DWORD dwFlags)
{
PerIOData * pData = (PerIOData*)lpOverlapped;
if (dwError != 0 || cbTransferred == 0) {
_pThis->_eventHandler.OnConnectionClose(pData);
_pThis->_ssMngr->Release(pData);
return;
}
_pThis->_eventHandler.OnDataArrival(cbTransferred, pData);
pData->ResetBuffer();
WSARecv(pData->s, &pData->buf, 1, 
&pData->bytes_received, &pData->flags,
&pData->ovl, completionRoutine);
}发现如果WSARecv中给定的WSABUF太小,而需要接收的数据很多的时候,完成例程会被调用多次直到数据全部接收完,此时在后面的WSAWaitForMultipleEvents调用会返回WSA_IO_COMPLETION表明一次I/O操作已全部完成,此时怎样判断完成的I/O操作是在哪个SOCKET上的呢?

解决方案 »

  1.   


    struct PerIOData
    {
      WSAOVERLAPPED m_OverLapped;
      ......   SOCKET   m_SockBelongTo;  //该IO所属的SOCKET,在初始化该结构的时候可以把相应的SOCKET赋值给它,但是不要调用    
                                      //CloseSocket(m_SockBelongTo)来关闭,只是一个KEY而已
    }接收后几可以通过该m_SockBelongTo来找到在哪个SOCKET上完成的操作了
      

  2.   

    我的PerIOData里是有socket的:
    struct PerIOData
    {
    WSAOVERLAPPED ovl;
    SOCKET s;
    WSABUF buf;
    DWORD bytes_received;
    DWORD flags;
    char _internal_buf[BUF_SIZE];
    };问题是WSAWaitForMultipleEvents方法返回WSA_IO_COMPLETION的时候,无法判断是哪个SOCKET产生的
      

  3.   

    根据 ovl 反获取到 PerIOData(这个应该会吧?有现成的宏可以用)
    就可以知道socket了(PerIOData的s)
      

  4.   

    在WSAWaitForMultipleEvents方法返回WSA_IO_COMPLETION的时候,根本就得不到OVERLAPPED*的信息啊,能得到的话也不会有这个问题了
      

  5.   

    顺便问下,用什么宏可以从ovl直接得到PerIOData?