美文网首页
iOS之Protobuf拆包和粘包问题处理

iOS之Protobuf拆包和粘包问题处理

作者: 谈daxia | 来源:发表于2017-04-17 00:28 被阅读295次

在上一篇文章《iOS之ProtocolBuffer搭建和示例demo》分享环境的搭建, 我们和服务器进行IM通讯用了github有名的框架CocoaAsynSocket, 然后和服务器之间的数据媒介是ProtoBuf。然后后面在开发的过程中也碰到了拆包和粘包问题,这方面网上资料很少,曲折了一下才解决,这里分享一下问题的解决过程!

首先描述下碰到的问题:

1、服务器发送内容很长的数据过来的时候,GCDAsyncSocket监听收到的一个包解析不了,一直要接收好几个包拼接才是这条数据的完整包,即所谓的拆包;

2、服务器快速发送多条数据过来,传到客户端这边的时候几条数据合成了一个包,即所谓的粘包。所以想解析这些粘在一起的数据,必须知道每条数据的长度,才能正确切割解析。

先上关键代码,解决读取每条数据的头部字节,根据头部字节读取这条数据的内容长度。这样才能完美的解决粘包问题。由于根据数据的长度不一样,导致头部字节占用的长度也会不一样,比如说我这里反复测试的结果头部占用字节一般为1和2,短内容数据头部占用字节长度为1,长内容数据头部占用字节长度为2。这里的代码参考了谷歌提供的Protobuf的objectivec版的源码。

关键代码,读取每条数据的头部占用字节,和内容长度:

/**获取data数据的内容长度和头部长度: index -->头部占用长度(头部占用长度1-4个字节) */

- (int32_t)getContentLength:(NSData *)data withHeadLength:(int32_t *)index{

       int8_t tmp = [self readRawByte:data headIndex:index];

      if(tmp >=0) return tmp;

      int32_t result = tmp & 0x7f;

      if((tmp = [self readRawByte:data headIndex:index]) >=0) {

         result  |= tmp << 7;

      }else{

         result  |= (tmp & 0x7f) << 7;

        if((tmp = [self readRawByte:data headIndex:index]) >=0) {

           result  |= tmp << 14;

        }else{

          result  |= (tmp & 0x7f) << 14;

         if((tmp = [self readRawByte:data headIndex:index]) >=0) {

            result  |= tmp << 21;

        }else{

          result  |= (tmp & 0x7f) << 21;

         result  |= (tmp = [self readRawByte:data headIndex:index]) << 28;

        if(tmp <0) {

           for(inti =0; i <5; i++) {

               if([self readRawByte:data headIndex:index] >=0 ) {

                   return result;

                }

          }

          result = -1;

     }

   }

  }

  }  

return result;

}

/**读取字节*/

- (int8_t)readRawByte:(NSData *)data headIndex:(int32_t *)index{

   if(*index >= data.length) return -1;

  *index = *index +1;

 return ((int8_t *)data.bytes)[*index -1];

}

原文链接见:CocoaAsyncSocket + Protobuf 处理粘包和拆包问题

demo链接:https://github.com/xiaotanit/Tan_ProtocolBuffer

相关文章

  • iOS之Protobuf拆包和粘包问题处理

    在上一篇文章《iOS之ProtocolBuffer搭建和示例demo》分享环境的搭建, 我们和服务器进行IM通讯用...

  • Netty系列(3)TCP的粘包拆包问题及方案

    1.概述 1.1 粘包拆包问题描述 1.2 粘包拆包产生的原因 1.3 粘包拆包问题的解决思路 2.Netty中粘...

  • 即时通讯

    iOS即时通讯,从入门到“放弃”?socket的半包,粘包与分包的问题iOS 处理socket粘包问题iOS___...

  • netty的编解码

    什么是拆包/粘包 TCP 粘包/拆包 半包:读取的数据不是一个数据包粘包:读取的数据超过一个数据包 粘包问题的解决...

  • iOS Socket封包、粘包、拆包处理

    一、封包 在iOS很多应用开发中,大部分用的网络通信都是http/https协议,除非有特殊的需求会用到Socke...

  • TCP协议下的粘包与拆包,如何解决

    TCP协议下的粘包与拆包,如何解决 TCP协议下的粘包与拆包,如何解决一、粘包、拆包1.1 粘包原因1.1.1 滑...

  • TCP粘包和拆包

    TCP的粘包和拆包 粘包和拆包现象 客户端给服务端发送数据可能存在的场景: 1.无拆包粘包 服务端分两次读取到了两...

  • TCP粘包

    什么是TCP粘包问题 多个TCP包粘在一个成为一个包,服务端处理接收的TCP包时,需要考虑拆包问题。 产生原因 发...

  • Netty 权威指南笔记(三):TCP 粘包和拆包

    Netty 权威指南笔记(三):TCP 粘包和拆包 什么是 TCP 粘包和拆包? TCP 是一个“流”协议,所谓“...

  • JAVA-每日一面 2022-01-25

    什么是 TCP 粘包/拆包以及TCP 粘包/拆包的解决办法 TCP 粘包/拆包1、要发送的数据大于 TCP 发送缓...

网友评论

      本文标题:iOS之Protobuf拆包和粘包问题处理

      本文链接:https://www.haomeiwen.com/subject/mxpzattx.html