netty十八罗汉之——挖耳罗汉(Decoder)

佛教中除不听各种淫邪声音之外,更不可听别人的秘密。因他论耳根最到家,故取挖耳之形,以示耳根清净。

来看看netty的核心组件解码器Decoder

  •  Decoder的作用
  • 半包,粘包问题
  • 从模板和装饰器模式看Decoder解码原理

1.Decoder作用

 最根本的就是将网络中的二进制数据,解析成为目标对象(Object)。

抽象出来本质就是上图,其它任何动作都是在完成这个目的。

对吧,学习一定要抓住本质。

先来看看网络数据再网络和操作系统底层是怎么传输的

a.网络数据是以二进制的数据包进行传输的,在netty中是以bytefuf数据包进行传递。这个概念之     后  章节会讲到。

b.会涉及tcp/ipc传输协议。

 先来看看TCP/IP协议的数据封装和分用过程,大致如下图所示:

 

可以看到没往下传输一层,会加上一个每层的首部。这个可以理解为,唐僧西天取经的过程中,通关文牒都要盖一个章一样。不加这个人家不认你。用的时候在解析出来报文体。

这里就不得不提一个概念MSS(TCP[数据包]每次能够传输的最大数据分段)

后面在传输过程中,超过这个值,数据包会进行拆分;小于这个值,数据包会进行合并。

c.dma复制

简单讲 就是绕过cpu,直接操作内存在设备间传输数据。

具体流程如下:

dam传输数据时,cpu不参与,dma处理完之后通知cpu进行后续处理。

理解这几个点之后,我们再来看一看正真的数据传播流程:

1.首先发送端,在用户缓存区里的bytebuf数据包会进行一次cpu复制;

2.cpu复制之后数据会缓存在发送缓冲区的内核空间里,这时候数据是完整的;

3.内核缓冲区进行一次DMA复制,数据被写入网卡设备中,此时网卡里面的数据包会进行重组;

4.写入网卡的数据通过TCP/IP协议进行传输,组装成新的二进制数据包,有最大数据限制;

5.接收端通过TCP/IP协议接收到二进制数据包,此时数据是完整的;

6.接收端在内核缓冲区进行一次DMA复制,形成新的bytebuf数据包;

7.接收端进行一次cpu复制,bytebuf数据包被写入用户缓冲区。

具体流程如下图:

这个过程会涉及两次分割二进制包:

a.传输过程中的分割;

b.系统复制过程中的分割;

所以粘包,和半包问题的出现就发生在这两个过程中,数据包少了,多个合在一起就会造成粘包。数据包多了,就会进行分割,分割就会打破原来的数据结构,出现半包问题。

来看看netty Decoder是怎么解决这个问题的

1.通过ByteToMessageDecoder 将二进制数据转换成对象

2.通过MessageToMessageDecoder将对象数据转换成对象

先来看看ByteToMessageDecoder 它是一个基类,主要使用模板方法接受管理bytebuf,子类通过实现钩子方法,处理业务逻辑,处理完业务逻辑将写入List<Object>中,之后在流水线上发送到下一站。流水线概念会在之后一章单独讲解。

public class Byte2IntegerDecoder extends ByteToMessageDecoder {

    //钩子实现
    @Override
    public void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
        while (in.readableBytes() >= 4) {
            Integer anInt = in.readInt();
            Logger.info("解码出一个整数: " + anInt);
            out.add(anInt);
        }
    }
}

来看看它的具体使用,继承ByteToMessageDecoder,钩子方法里实现业务逻辑。

回顾一下什么是模板方法:

核心点:抽象类会实现一系列公共方法共子类使用。

1.抽象类会定义一系列的模板方法,子类自动继承。

2.子类通过钩子方法处理具体业务逻辑。

好,我们再看一个它的核心子类ReplayingDecoder(回放解码器)。

什么是回放呢?

我们读取数据的时候是在操作一个二进制数组,数组元素完整的话,指针移动没有问题。但是数据元素不完整,再次读取的时候记数指针会回到开头重新执行。

netty通过checkpoint指针来完成指针回放

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值