通信长连接并包头+包长处理方式

第一种方式:
 // 向服务器发送数据
 SOCKET soc = *( ks->GetSocket() );

 char xmlLen[4];   // 表示包体长度的串

 char redstr[1024];  // 一个完整的数据包
 // char sendBuffer[512]; // 发缓冲
 int  bodyLength = 0; // 包长度

 int ret;    // socket收的返回值
 char redBuffer[51200]; // 读缓冲
 int xmlIndex = 0;  // 处理缓冲的最后位
 char xmlBuffer[102400]; // 处理缓冲

 // 循环堵塞收数据
 while(1){
  ret = recv(soc, redBuffer, 51200, 0);

  if(ret == 0)                                 //Graceful   close  
   break;
  else if(ret == SOCKET_ERROR){
   printf("recv()   failed:   %d/n",WSAGetLastError());  
   break;
  }

  for(int i = 0; i < ret; i++){
   xmlBuffer[i + xmlIndex] = redBuffer[i];
  }
  xmlIndex += ret;

  int redIndex = 0;
  while(1){
   if(bodyLength == 0 && (5 + redIndex) >= xmlIndex){
    xmlIndex -= redIndex;
    break;
   }

   if(bodyLength == 0){
    for(int i = 0; i < 4; i++){
     xmlLen[i] = xmlBuffer[i+1];
    }
    bodyLength = Char2Int(xmlLen,4);
    redIndex += 5;
   }

   if(( xmlIndex - redIndex) >= bodyLength){
    for(int i = 0; i < bodyLength; i++){
     redstr[i] = xmlBuffer[i + redIndex];
    }
    redstr[bodyLength] = '/0';

    redIndex += bodyLength;
    bodyLength = 0;

   }else{
    int count =  xmlIndex - redIndex - 5;

    for(int i = 0; i < count; i++){
     xmlBuffer[i] = xmlBuffer[i + redIndex + 5];
    }
    xmlIndex = count;
    break;
   }
  }

 

第二种方式:

  /*  
  nReadLen = recv(soc, ver, 1, 0);
  if (SOCKET_ERROR == nReadLen) {   
  Log::Info("Socket读版本信息错误");
  continue;
  }  
  if (0 == nReadLen) {
  Log::Info("Socket接收版本信息出错");
  continue;
  }

  // 消息的主体长度
  nReadLen = recv(soc, xmlLen, 4, 0);
  if (SOCKET_ERROR == nReadLen) {   
  Log::Info("Socket读XML包数据长度错误");
  continue;
  }
  if (0 == nReadLen) {
  Log::Info("Socket接收XML包数据长度出错");
  continue;
  }

  bodyLength = Char2Int(xmlLen,4);

  CString ss = "";
  ss.Format("%d",bodyLength);
  //    Log::Info("包长度");
  //    Log::Info(ss);

  nReadLen = recv(soc, redBuffer, bodyLength, 0);
  if (SOCKET_ERROR == nReadLen) {
  Log::Info("Socket读消息体错误");
  continue;   // 跳出循环      
  }
  if (0 == nReadLen) {
  Log::Info("Socket接收消息体出错");
  continue;   // 跳出循环   
  }
  redBuffer[bodyLength] = '/0';
  CString sss = "";
  sss.Format("%s",redBuffer);

  Log::Info(sss);
  //    CString redMsg = EvtSocket(sss);
  CString redMsg = "";
  int nDataLen = 0;
  */
  
 }

 return 0;

 

第三种方式

LRESULT CMySocketClient::OnClientReceive(WPARAM wParam, LPARAM lParam)
{
 //char *buf = new char[100];
 CString str;
 //m_DataBufferSizeLast++;

 switch (WSAGETSELECTEVENT(lParam))
 {
 case FD_READ:
  {
   //return 0L;
   int TempDataBufferSize=DataBufferSize - m_DataBufferSizeLast;
   char* DataBuffer = new char[TempDataBufferSize];
   memset(DataBuffer, 0, sizeof(char)*TempDataBufferSize );
   try
   {
    m_receivedBytesSize =recv(m_hSocket,DataBuffer,TempDataBufferSize,0);
    if (m_receivedBytesSize <=0)  //SOCKET_ERROR
       {
        AfxMessageBox("接收数据发生错误。");
        return 0L;
       }


    m_receivedBytesSizeLast=m_receivedBytesSize+m_DataBufferSizeLast;   //socket 收到的数据 与上次流下的数据总和
    char* TempBytes = new char[m_receivedBytesSizeLast];
    memset(TempBytes, 0, sizeof(char)*m_receivedBytesSizeLast );
    try
    {
     if(m_DataBufferSizeLast>0)
     {
      memcpy(TempBytes,m_DataBufferLast,m_DataBufferSizeLast);
      m_DataBufferSizeLast=0;
     }
     memcpy(TempBytes,DataBuffer,m_receivedBytesSize);
     EncodingBytes(TempBytes, m_receivedBytesSizeLast);

    }catch(std::exception &e)
    {

    }
    
    delete [] TempBytes; //socket 收到的数据 与上次流下的数据总和

   }catch(std::exception &e)
   {
       //delete [] DataBuffer;
   }
   delete [] DataBuffer;  //socket 收到的数据

  
  }
  
  break;
 case FD_CLOSE:
  closesocket(m_hSocket);
  AfxMessageBox("服务器退出。");  
  break;
 }
 return 0L;
}

 


int CMySocketClient::EncodingBytes(char Totalbytes[], int TotalBytesCount)
{
 try
 {
  if (TotalBytesCount<=5)
  {
   memcpy(m_DataBufferLast,Totalbytes,TotalBytesCount);
   m_receivedBytesSize=TotalBytesCount;  
   return 0;
  }


  char TempHeadBytes[4];    //第一位是版本号 ,第二到第5是包的长度
  char a;
  for (int i = 0; i < 4; i++)
  {
   a=Totalbytes[1+i];  
   TempHeadBytes[i] = Totalbytes[1+i];  
  }
  int TempPackLen = ChartoInt(TempHeadBytes, 4);     //每个包的长度


  if ((TempPackLen + DataHeadLen) > TotalBytesCount)  //如果接收的数据还达不到定义的长度返回
  {
   memcpy(m_DataBufferLast,Totalbytes,TotalBytesCount);
   m_receivedBytesSize=TotalBytesCount;
   return 0;  
   }

  char* TempPackBytes = new char[TempPackLen+1];
  memset(TempPackBytes, 0, sizeof(char)*TempPackLen );
  //char a;  
  for (int i = 0; i < TempPackLen; i++)
        {         
   TempPackBytes[i] = Totalbytes[i + DataHeadLen];    
        }
  TempPackBytes[TempPackLen]='/0';
  //CString str=TempPackBytes;  //  str1.Format("%s", TempPackBytes);         str11=TempPackBytes   (char*)TempPackBytes;

  m_CallbackOutput->Execute((void*)TempPackBytes);
  delete [] TempPackBytes;  


  if ((TempPackLen + DataHeadLen) < TotalBytesCount)  //第一次取完后还的内容处理
  {
   char* Bytes = new char[TotalBytesCount - DataHeadLen - TempPackLen];
   memcpy(Bytes,Totalbytes+DataHeadLen+TempPackLen,TotalBytesCount - DataHeadLen - TempPackLen);
   EncodingBytes(Bytes,TotalBytesCount - DataHeadLen - TempPackLen);
  }

 }catch(std::exception &e)
 {
  CString str1=e.what();
 }
 return 0L;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值