美文网首页
CocoaAsyncSocket 学习(二) 数据粘包、断包处理

CocoaAsyncSocket 学习(二) 数据粘包、断包处理

作者: Rui哥 | 来源:发表于2018-02-28 11:45 被阅读32次

    原文参考:https://www.jianshu.com/p/2e16572c9ddc

    一、什么是粘包?

    经常我们发现,如果用客户端同一时间发送几条数据,而服务端只能收到一大条数据

    TCP 数据传输为什么会造成粘包呢?

    原来这是因为TCP使用了优化方法(Nagle算法)。
    它将多次间隔较小且数据量小的数据,合并成一个大的数据块,然后进行封包。
    这么做优点也很明显,就是为了减少广域网的小分组数目,从而减小网络拥塞的出现。

    而UDP就不会有这种情况,它不会使用块的合并优化算法。
    这里说到了就顺便提一下,由于它支持的是一对多的模式,所以接收端的skbuff(套接字缓冲区)采用了链式结构来记录每一个到达的UDP包,在每个UDP包中就有了消息头(消息来源地址,端口等信息)。

    当然除了优化算法,TCP和UDP都会因为下面两种情况造成粘包:
    发送端需要等缓冲区满才发送出去,造成粘包
    接收方不及时接收缓冲区的包,造成多个包接收。

    二、什么是断包?

    断包应该还是比较好理解的,比如我们发送一条很大的数据包,类似图片和录音等等,很显然一次发送或者读取数据的缓冲区大小是有限的,所以我们会分段去发送或者读取数据。

    三、实例:基于CocoaAsyncSocket的封包,拆包处理。

    开始动手之前,我们需要去理解下面这几个方法

    //读取数据,有数据就会触发代理
    - (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag;
    //直到读到这个长度的数据,才会触发代理
    - (void)readDataToLength:(NSUInteger)length withTimeout:(NSTimeInterval)timeout tag:(long)tag;
    //直到读到data这个边界,才会触发代理
    - (void)readDataToData:(NSData *)data withTimeout:(NSTimeInterval)timeout tag:(long)tag;
    
    

    CocoaAsyncSocket 这个框架每次读取数据,必须手动的去调用上述这些read方法,而我们之前的实现思路是,第一次连接成功的代理触发后调用:

    - (void)readDataWithTimeout:(NSTimeInterval)timeout tag:(long)tag;
    

    之后每次收到消息之后,都在去调用一次这个方法,超时为-1,即不超时。这样我们每次收到消息,都会即时触发我们读取消息的代理:

    - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag
    

    然而这么做显然没有考虑数据的拆包,如果我们一条一条的发送文字信息,自然没什么问题。如果我们一次发送数条,或者发送大图片。那么问题就出来了,我们解析出来的数据显然是不对的。

    这时候我们就需要另外两个read方法了,一个是读取到指定长度,另一个是读取到指定边界。

    我们通过自己定义的数据边界,去调用这两个方法,而触发的读取代理,得到的数据才是正确的一个包的数据。

    所以我们的核心思路有了:

    • 1、封包的时候给每个包的数据加一个标记,来标明数据的长度和类型(类型显然是需要的,我们需要知道它是文本、图片、还是录音等等,来用正确的方式处理这个数据)。

    • 2、拆包的时候,先获取到我们给每个包的标记,然后根据标记的数据长度,去获取数据。最后再根据标记的类型去处理数据。(文字输出、图片展示、录音播放等等)。

    [newSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:110];

    还记得我们封包的时候,数据包头部之后拼了这么一个分解符`data`。这样,当有数据包传输过来我们就能获取到这个数据包的头部(后面的信息先不读取)。
    
    接着我们来看看服务端的`read`代理方法是如何拆包的:
    

    相关文章

      网友评论

          本文标题:CocoaAsyncSocket 学习(二) 数据粘包、断包处理

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