大家都知道,网络tcp,流socket是不能保证收到的包是逻辑完整的,也许一个逻辑完整的被分成两段发送,所以我们使用流socket就需要将接收的包(物理包),网站优化,经过整理变成逻辑包。然后再处理。这个整理包的函数就是所说的拼包函数。下面的代码用环形缓冲实现了一个拼包函数。环形缓冲可以减少不必要memcpy,从而提高效率。
![](http://blog.vckbase.com/Images/OutliningIndicators/None.gif)
//这是per-I/O数据。它包含了在套节字上处理I/O操作的必要信息
![](http://blog.vckbase.com/Images/OutliningIndicators/None.gif)
structTPerIoData
![](http://blog.vckbase.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
OVERLAPPEDol;//重叠io,必须为第一个数据
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
WSABUFdataBuf;//投递数据时的结构
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
charbuff[IO_BUF_LEN];//接收或发送的io数据的buffer
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
intbufferLen;//buffer长度
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
SOCKETsClient;//在Accept一个连接后,通过它传递连接的客户端
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
intopType;//操作类型:Operation_type
![](http://blog.vckbase.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
};
![](http://blog.vckbase.com/Images/OutliningIndicators/None.gif)
![](http://blog.vckbase.com/Images/OutliningIndicators/None.gif)
//这是per-Handle数据。它包含了一个套节字的信息
![](http://blog.vckbase.com/Images/OutliningIndicators/None.gif)
structTIOCPContext
![](http://blog.vckbase.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
SOCKETs;//套节字句柄
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
SOCKADDR_INaddrRemote;//连接的远程地址
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
BOOLbClosing;//套节字是否关闭
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
intnPostNum;//此套节字上抛出的重叠操作的数量
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
BYTE*lpBufBegin;//拼包缓冲区头指针
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
BYTE*lpBufEnd;//拼包缓冲区尾指针
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
intarrayDataLen;//拼包缓冲目前长度
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
BYTEarrayDataBuf[USE_DATA_LONGTH];//拼包缓冲区
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
CRITICAL_SECTIONLock;//保护这个结构
![](http://blog.vckbase.com/Images/OutliningIndicators/ExpandedBlockEnd.gif)
};
![](http://blog.vckbase.com/Images/OutliningIndicators/None.gif)
![](http://blog.vckbase.com/Images/OutliningIndicators/None.gif)
boolCUserServer::SplitPacket(TIOCPContext*pContext,TPerIoData*pBuffer,char*outBuf)
{
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
intrecvedCount=pBuffer->bufferLen;//收到的数据长度
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
//守卫pContext结构
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
CGuardLock(&pContext->Lock);
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
//如果缓冲区不够,说明包格式有问题,则丢弃数据
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
if(USE_DATA_LONGTH-pContext->arrayDataLenlpBufBegin=pContext->lpBufEnd=pContext->arrayDataBuf;
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
pContext->arrayDataLen= 0;
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
return false;
![](http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
intlastLen;
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
//将接收的数据copy到整理缓冲区
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
if(pContext->lpBufEndlpBufBegin)//假如尾指针在头指针前面
{
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
memcpy(pContext->lpBufEnd,pBuffer->buff,recvedCount);
}
else
{
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
lastLen=USE_DATA_LONGTH-(pContext->lpBufEnd-pContext- >arrayDataBuf);//尾指针到缓冲最后位置的大小
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
if(lastLenlpBufEnd,pBuffer->buff,lastLen);
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
memcpy(pContext->arrayDataBuf,pBuffer- >buff+lastLen,recvedCount-lastLen);
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
![](http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
memcpy(pContext->lpBufEnd,pBuffer->buff,recvedCount);
![](http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
//更新尾指针
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
if(lastLenlpBufEnd=pContext->arrayDataBuf+recvedCount-lastLen;
![](http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
else
![](http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://blog.vckbase.com/Images/OutliningIndicators/ContractedSubBlock.gif)
{
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
pContext->lpBufEnd+=recvedCount;
![](http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
//更新缓冲长度
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
pContext->arrayDataLen+=recvedCount;
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
//按照包格式判断包是否完整,包格式=type(4byte)+packetlen(4byte)+content
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
if(pContext->arrayDataLen< 8)//收到的包不完整
![](http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
//返回,
网站SEO,等下次再整理
![](http://blog.vckbase.com/Images/OutliningIndicators/InBlock.gif)
return false;
![](http://blog.vckbase.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif)
}