Chinaunix首页 | 论坛 | 博客
  • 博客访问: 372838
  • 博文数量: 715
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5005
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:46
文章分类

全部博文(715)

文章存档

2011年(1)

2008年(714)

我的朋友

分类:

2008-10-13 16:35:13

  // 这是per-I/O数据。它包含了在套节字上处理I/O操作的必要信息
struct TPerIoData
{
 OVERLAPPED ol;                      
//重叠io,必须为第一个数据
 WSABUF     dataBuf;                 //投递数据时的结构
 char       buff[IO_BUF_LEN];        //接收或发送的io数据的buffer
 int        bufferLen;               //buffer长度
 SOCKET     sClient;                 // 在Accept一个连接后,通过它传递连接的客户端
 int        opType;                  // 操作类型:Operation_type
}
;

// 这是per-Handle数据。它包含了一个套节字的信息
struct TIOCPContext
{
 SOCKET s;              
// 套节字句柄
 SOCKADDR_IN addrRemote;   // 连接的远程地址
 BOOL bClosing;         // 套节字是否关闭
 int nPostNum;             // 此套节字上抛出的重叠操作的数量
 BYTE* lpBufBegin;           //拼包缓冲区头指针
  BYTE* lpBufEnd;             //拼包缓冲区尾指针
  int arrayDataLen;           //拼包缓冲目前长度
  BYTE arrayDataBuf[USE_DATA_LONGTH]; //拼包缓冲区
 CRITICAL_SECTION Lock;   // 保护这个结构
}
;

bool CUserServer::SplitPacket(TIOCPContext *pContext, TPerIoData *pBuffer, char* outBuf)
{
 
int recvedCount = pBuffer->bufferLen; //收到的数据长度
 
//守卫pContext结构
 CGuardLock(&pContext->Lock);
 
//如果缓冲区不够,说明包格式有问题,则丢弃数据
 if(USE_DATA_LONGTH - pContext->arrayDataLen < recvedCount)
 
{
  pContext
->lpBufBegin = pContext->lpBufEnd = pContext->arrayDataBuf;
    pContext
->arrayDataLen = 0;
  
return false;
 }

 
 
int lastLen  = USE_DATA_LONGTH - (pContext->lpBufEnd - pContext->arrayDataBuf); //尾指针到缓冲最后位置的大小
 
//将接收的数据copy到整理缓冲区
 if(pContext->lpBufEnd <= pContext->lpBufBegin) //假如尾指针在头指针前面
 {
  memcpy(pContext
->lpBufEnd, pBuffer->buff, recvedCount);
 }

 
else 
 
{
  
  if(lastLen < recvedCount) //不能完全copy到最后
  {
   memcpy(pContext
->lpBufEnd, pBuffer->buff, lastLen);
   memcpy(pContext
->arrayDataBuf, pBuffer->buff + lastLen, recvedCount - lastLen);
   
  }

  
else
  
{
   memcpy(pContext
->lpBufEnd, pBuffer->buff, recvedCount);
  }

 }

 
//更新尾指针
 if(lastLen <= recvedCount)
 
{
  pContext
->lpBufEnd = pContext->arrayDataBuf + recvedCount - lastLen;
 }

 
else
 
{
  pContext
->lpBufEnd += recvedCount;
 }

 
//更新缓冲长度
 pContext->arrayDataLen += recvedCount;
 
 
//根据包格式判断包是否完整,包格式 = type(4byte) + packetlen(4byte) + content
 if(pContext->arrayDataLen < 8//收到的包不完整
 
  
//返回,等下次再整理
  return false;
 }

 char tmpBuf[10] = {'\0'};
 lastLen = USE_DATA_LONGTH - (pContext->lpBufBegin - pContext->arrayDataBuf); //头指针到整理缓冲末尾的大小
 if(lastLen < 8)
 {
  memcpy(tmpBuf, pContext->lpBufBegin, lastLen);
  memcpy(tmpBuf + lastLen, pContext->arrayDataBuf, 8 - lastLen);
 }
 else
 {
  memcpy(tmpBuf, pContext->lpBufBegin, 8);
 }
 //得到包长度
 int packLen = atoi(tmpBuf + 4);
 if(packLen > MAX_PACKET_LEN || packLen < 0 )
 {
  //包长度有问题,则丢弃现在缓冲中的消息
  pContext->lpBufBegin = pContext->lpBufEnd = NULL;
  pContext->arrayDataLen = 0;
  return false;
 }
 if(packLen > pContext->arrayDataLen - 8)
 {
  //包还不完整,等下次再整理
  return false;
 }
 
 //现在将逻辑完整的包copy到out参数中去
 if(lastLen < 8 + packLen)
 {
  memcpy(outBuf, pContext->lpBufBegin, lastLen);
  memcpy(outBuf + lastLen, pContext->arrayDataBuf, 8 + packLen - lastLen);
 }
 else
 {
  memcpy(outBuf , pContext->lpBufBegin, 8 + packLen);
 }
 
 //更新头指针
 if(lastLen <= 8 + packLen)
 {
  pContext->lpBufBegin = pContext->arrayDataBuf + 8 + packLen - lastLen;
 }
 else
 {
  pContext->lpBufBegin += (8 + packLen);
 }
 //更新长度
 pContext->arrayDataLen -= 8 + packLen;
 return true;

--------------------next---------------------

阅读(210) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~