完成例程如下:
========================
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上的呢?
5 个解决方案
我的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产生的
根据 ovl 反获取到 PerIOData(这个应该会吧?有现成的宏可以用)
就可以知道socket了(PerIOData的s)
在WSAWaitForMultipleEvents方法返回WSA_IO_COMPLETION的时候,根本就得不到OVERLAPPED*的信息啊,能得到的话也不会有这个问题了