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,因为不通命令可能带的值不一样,所以也就必须定义此命令的长度。这在连包处理上非常重要。

  • 相关阅读:
    我是如何基于angular+requirejs+node做SPA项目架构的
    阿里云无线&前端团队是如何基于webpack实现前端工程化的
    angularjs源码分析之:angularjs执行流程
    你所必须掌握的三种异步编程方法callbacks,listeners,promise
    自从用了Less 编写css,你比以前更快了~
    对象的深浅拷贝
    throttle/debounce: 为你的cpu减减压(前端性能优化)
    jekyll : 使用github托管你的博客
    html5 drag api详解
    用setTimeout 代替 setInterval实时拉取数据
  • 原文地址:https://www.cnblogs.com/kanite/p/5038960.html
Copyright © 2011-2022 走看看