Netty如何解决粘包拆包?(二)


前言

TCP是个流协议,所谓流,就是没有界限的一串数据。你们能够想一想河里的流水,是连成一片的,其间并无分界线。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际状况进行包的划分,因此在业务上认为,一个完整的包可能会被TCP拆分红多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。app

案例:
源码分析

          

       某时刻发送端缓冲区太小,致使ABC数据包发生拆包成AB、C,拆分出来的C与数据包DEF粘包发送给接收端。
指针

拆包场景:netty

(1)要发送的数据大于缓冲区剩余大小;code

(2)待发送的数据大于MSS,TCP会在传输前将其拆分;orm

粘包场景:cdn

(1)要发送小于缓冲区剩余大小;blog

(2)接受数据端的应用层没来得及读取缓冲区的数据;继承

应用层协议存在粘包拆包状况,netty如何利用Frameecoder来解决的?get

在Netty的codec模块中,对通用传输协议提供了支持,而且在FrameDecoder中对于粘包拆包给出了通用的解决方案,应用层协议解析类能够经过继承它而无须担忧粘包、拆包等问题。


        能够看到http协议解析类HttpMessageDecoder固定、长度解析类FixedLengthFrameDecoder、换行协议解析类LineBaseFrameDecoder等等都是基于FrameDecoder拓展实现,而FrameDecoder继承自SimpleChannelUpstreamHandler,是否是有点熟悉呢?没错,这个在解读netty3.9的数据处理流程(一)的处理执行者,没看过的同窗能够点进去看看。

拨开浓雾:

         对于脉络咱们已经梳理清晰,拆包粘包是前文数据处理流程的某一个环节,那到底FrameDecoder为何那么神奇,能通用地处理粘包呢?能够想象,仓库包裹打包出库场景,打包人员在工做台打包货物,直到缺乏货物再让拣选员拣选过来接着打包,缺货的时候是否是还有商品在工做台上,是否是有点懂了FrameDecoder在作什么事呢?能够理解就是一个打包工做台,还无法打包就等待可是注意货物还在台上,能够打包就一直打包下去便可。

那咱们来看看FrameDecoder庐山真面目。


       能够看到cumulation不为空的状况下,就调用appendToCumulation将接受到的数据塞到cumulation中,cumulation就是刚刚货物打包场景中的工做台,不然就调用callDecode循环地去解析应用数据包,而且调用updateCumulation订正cumulation的数据。


       当cumulation可读时,记录下旧的读指针用于对比,并调用实际的协议执行者解析出应用层数据包。

       一、若是数据包为空而且读指针未挪动,说明应用层数据包不全,跳出等待数据;

       二、若是数据包为空可是读指针挪动,抛弃部分数据可能正在读,继续调用解析;

       三、若是存在数据包而且读指针未移动,则抛出异常;

       四、若是数据包不为空而且读指针挪动,很明显继续调用解析;


       喜欢的读者能够关注路上小栈,及时获取最新的技术文章,专一源码分析、技术业务思考等。

相关文章
相关标签/搜索