|
具体的看看接受代码:
// 接收完成函数
bool CServerSocketItem::OnRecvCompleted(COverLappedRecv * pOverLappedRecv, DWORD dwThancferred)
{
// 效验数据
ASSERT(m_bRecvIng== true);
// 设置变量
m_bRecvIng= false;
m_dwRecvTickCount=GetTickCount();
// 判断关闭
if (m_hSocket==INVALID_SOCKET)
{
CloseSocket(m_wRountID);
return true;
}
// 接收数据
int iRetCode=recv(m_hSocket,( char *)m_cbRecvBuf+m_wRecvSize, sizeof(m_cbRecvBuf)-m_wRecvSize,0);
if (iRetCode<=0)
{
CloseSocket(m_wRountID);
return true;
}
// 接收完成
m_wRecvSize+=iRetCode;
BYTE cbBuffer[SOCKET_BUFFER];
CMD_Head * pHead=(CMD_Head *)m_cbRecvBuf;
// 处理数据
try
{
while (m_wRecvSize>= sizeof(CMD_Head))
{
// 效验数据
WORD wPacketSize=pHead->CmdInfo.wDataSize;
if (wPacketSize>SOCKET_BUFFER) throw TEXT("数据包超长");
if (wPacketSize< sizeof(CMD_Head)) throw TEXT("数据包非法");
if (pHead->CmdInfo.cbMessageVer!=SOCKET_VER) throw TEXT("数据包版本错误");
if (m_wRecvSize<wPacketSize) break;
// 提取数据
CopyMemory(cbBuffer,m_cbRecvBuf,wPacketSize);
WORD wRealySize=CrevasseBuffer(cbBuffer,wPacketSize);
ASSERT(wRealySize>= sizeof(CMD_Head));
m_dwRecvPacketCount++;
// 解释数据
WORD wDataSize=wRealySize- sizeof(CMD_Head);
void * pDataBuffer=cbBuffer+ sizeof(CMD_Head);
CMD_Command Command=((CMD_Head *)cbBuffer)->CommandInfo;
// 内核命令
if (Command.wMainCmdID==MDM_KN_COMMAND)
{
switch (Command.wSubCmdID)
{
case SUB_KN_DETECT_SOCKET: // 网络检测
{
break;
}
default: throw TEXT("非法命令码");
}
}
else
{
// 消息处理
m_pIServerSocketItemSink->OnSocketReadEvent(Command,pDataBuffer,wDataSize, this);
}
// 删除缓存数据
m_wRecvSize-=wPacketSize;
MoveMemory(m_cbRecvBuf,m_cbRecvBuf+wPacketSize,m_wRecvSize);
}
}
catch ( )
{
CloseSocket(m_wRountID);
return false;
}
return RecvData();
}
这是还是有分包算法的,总的来说接受流程如下:
直接使用recv把数据接受到SocketItem的缓冲区中,当长度大于CMD_HEAD之后,进入处理阶段,处理head数据各种判断,然后将数据扔出去,再调整缓冲区,,,
简单的说:
Send完全不考虑同步问题,不管一个劲的网队列投递Send请求,,,这边处理队列也是直接Send完事,完全不考虑上一次是否send成功,,,
Recv更是莫名其妙的使用完成端口绕一圈还回到recv直接接受了,,,
|
|