请留步,问个WSARecv/Send的问题
WSARecv/Send好像与Recv Send不太一样啊?
DWORD WINAPI ServerWorkerProc(LPVOID lParam)
{
CIocpModeSvr* pSvr=(CIocpModeSvr*)lParam;
HANDLE CompletionPort=pSvr->CompletionPort;
DWORD ByteTransferred;
LPPER_HANDLE_DATA PerHandleData;
PPER_IO_OPERATION_DATA PerIoData;
DWORD RecvByte;
while(true)
{
bool bSuccess=GetQueuedCompletionStatus(CompletionPort,
&ByteTransferred,
(LPDWORD)&PerHandleData,
(LPOVERLAPPED* )&PerIoData,
INFINITE);
//退出信号到达,退出线程
if(ByteTransferred==-1 && PerIoData==NULL)
{
return 1L;
}
//客户机已经断开连接或者连接出现错误
if(ByteTransferred==0 &&
(PerIoData->OperType==RECV_POSTED || PerIoData->OperType==SEND_POSTED))
{
//将该客户端数据删除
int arrSize=0;
bool bFind=false;
::EnterCriticalSection(&pSvr->cInfoSection);
while(arrSize<pSvr->ClientInfo.GetSize())
{
PER_HANDLE_DATA pPerHandleData=pSvr->ClientInfo.GetAt(arrSize);
if((pPerHandleData.IpAddr==PerHandleData->IpAddr) &&
(pPerHandleData.sClient==PerHandleData->sClient))
{
bFind=true;
pSvr->ClientInfo.RemoveAt(arrSize);
break;
}
arrSize++;
}
::LeaveCriticalSection(&pSvr->cInfoSection);
if(bFind)
{
//记录退出日志
CString LogStr;
in_addr in_A;
in_A.S_un.S_addr=PerHandleData->IpAddr;
LogStr.Format("Ip: %s,Socket : %d Disconneted",inet_ntoa(in_A),PerHandleData->sClient);
pSvr->WriteLogString(LogStr);
TRACE("\nSocket : %d Disconneted",PerHandleData->sClient);
//调用回调函数,通知上层该客户端已经断开
pSvr->m_pProcessRecvData(PerHandleData->IpAddr,
PerHandleData->sClient,
NULL,
0);
//关闭套接口
closesocket(PerHandleData->sClient);
GlobalFree(PerHandleData);
GlobalFree(PerIoData);
}
continue;
}
//为读操作完成,处理数据
if(PerIoData->OperType==RECV_POSTED)
{
//调用回调函数,处理数据
pSvr->m_pProcessRecvData(PerHandleData->IpAddr,
PerHandleData->sClient,
PerIoData->RecvBuf,
ByteTransferred);
//将源数据置空
memset(PerIoData->RecvBuf,0,BUFFER_SIZE);
ByteTransferred=0;
//重置IO操作数据
unsigned long Flag=0;
ZeroMemory(&(PerIoData->OverLapped),sizeof(OVERLAPPED));
PerIoData->RecvDataBuf.buf=PerIoData->RecvBuf;
PerIoData->RecvDataBuf.len=BUFFER_SIZE;
PerIoData->OperType=RECV_POSTED;
//提交另一个Recv请求
WSARecv(PerHandleData->sClient,
&(PerIoData->RecvDataBuf),
1,
&RecvByte,
&Flag,
&(PerIoData->OverLapped),
NULL);
}
//发送完成,置空缓冲区,释放缓冲区
if(PerIoData->OperType==SEND_POSTED)
{
memset(PerIoData,0,sizeof(PER_IO_OPERATION_DATA));
GlobalFree(PerIoData);
ByteTransferred=0;
}
}
return 0L;
}
上面的 "提交另一个Recv请求" WSARecv到底是是干什么用的?
事实上在IOCP里面GetQueuedCompletionStatus(CompletionPort,&ByteTransferred,(LPDWORD)&PerHandleData,(LPOVERLAPPED* )&PerIoData,INFINITE)本身已经可以捕获数据了,为什么还要WSARecv呢?