zoukankan      html  css  js  c++  java
  • 处理TCP连包的一小段代码

      学习网络编程也有一段时间了,一直听说TCP数据会连包,但一直不知道怎么测试好。最近测试了下:发送方使用对列,将发送的数据存入队列,然后开线程,专门发送。发送多包数据之间不延时。在接收方,他们确实连在一起了。花了点时间,写了一小段代码解决这个问题,其实一共也就4个函数:

     1 #define FIND_NO_HEAD 1024
     2 
     3 int MyTcpSock::GetPackageSetedLength(char *pHeader)
     4 {
     5     XX_NETPACKET_HEADER *pNetHeader = (XX_NETPACKET_HEADER *)pHeader;
     6 
     7     return (sizeof(XX_NETPACKET_HEADER) + pNetHeader->packetsize);
     8 }
     9 
    10 int MyTcpSock::FindHeaderFlag(char *buf,int len)
    11 {
    12     #define FLAGS_NUM 4
    13 
    14     int count = 0;
    15     char i=0;
    16     unsigned char Flags[FLAGS_NUM] = {XX_FLAG1,XX_FLAG2,XX_FLAG3,XX_FLAG4};
    17     XX_NETPACKET_HEADER *pHeader = (XX_NETPACKET_HEADER *)(buf+count);
    18 
    19     while(count < len)
    20     {
    21         for(i=0;i<FLAGS_NUM;i++)
    22         {
    23             if(pHeader->flag == Flags[i])
    24             {
    25                 return ((char *)pHeader - buf);
    26             }
    27         }
    28 
    29         count ++;
    30         pHeader = (XX_NETPACKET_HEADER *)(buf+count);
    31     }
    32 
    33     return FIND_NO_HEAD;
    34 }
    35 
    36 void MyTcpSock::ResolveRecievedData(char *buf,int len)
    37 {
    38     char *pUnreslovedData = (char *)buf;   //指向待解析的数据的开始
    39     int iUnreslovedDataLen = len;          //待解析的数据的长度
    40     int iHeaderPosition = 0;               //数据头的位置--相对于待解析的数据的起始位置
    41     int iPackageLen = 0;                   //解析出的命令的数据包长度
    42 
    43     while(iUnreslovedDataLen > 0)
    44     {
    45         iHeaderPosition = FindHeaderFlag(pUnreslovedData,iUnreslovedDataLen);
    46         if(iHeaderPosition == FIND_NO_HEAD)
    47         {
    48             TRACE("Find no Header!
    ");
    49             Printf(pUnreslovedData,iUnreslovedDataLen);
    50             return ;
    51         }
    52         iPackageLen = this->GetPackageSetedLength((char *)(pUnreslovedData+iHeaderPosition));
    53         if(iPackageLen > iUnreslovedDataLen)
    54         {
    55             TRACE("Package is not full!
    ");
    56             Printf(pUnreslovedData,iUnreslovedDataLen);
    57             return ;
    58         }
    59 
    60         ResolvePackageCmd((char *)(pUnreslovedData+iHeaderPosition),iPackageLen);
    61 
    62         pUnreslovedData = pUnreslovedData + iHeaderPosition + iPackageLen;  //调整指针
    63         iUnreslovedDataLen = iUnreslovedDataLen - iHeaderPosition - iPackageLen;
    64     }
    65 }
    66 
    67 void MyTcpSock::ResolvePackageCmd(char *buf,int len)
    68 {
    69     XX_NETPACKET_HEADER *pNetHeader = (XX_NETPACKET_HEADER *)buf;
    70 
    71         //XXX后面就是命令的解析了
    72 }
    View Code

      以上代码是C++,去掉类就是C。以上代码经过测试,可以解决如下问题:

      数据连包的问题。

      数据发送丢失,比如有包头却丢失了一些数据。后面解析这些命令时,如果以为数据存在,直接用将会出现不可预知的错误。

          命令包格式的设计,基本要遵守CLV的格式,C-code命令,L-Length命令长度,V-Value值。

      这里的命令也基本上就是上面的Flag,因为不通命令可能带的值不一样,所以也就必须定义此命令的长度。这在连包处理上非常重要。

  • 相关阅读:
    jQuery tips
    WCF4.0进阶系列—第十一章 编写代码控制配置和通信 (上)
    WCF4.0进阶系列—第九章 事务支持(上)
    WCF4.0进阶系列第二章 寄宿WCF服务
    WCF4.0进阶系列第五章 在因特网环境下保护WCF服务
    [JavaScript] onkeypress and onchange event
    [JavaScript]使用jQuery定制开发自己的UI
    WCF4.0进阶系列第四章 保护企业内部的WCF服务
    WCF4.0进阶系列第六章 维护服务协定和数据协定
    WCF4.0 进阶系列第一章 WCF简介
  • 原文地址:https://www.cnblogs.com/kanite/p/5038960.html
Copyright © 2011-2022 走看看