Netty源码解析之解码器

本文详细解析了Netty中的解码器基础类ByteToMessageDecoder,如何解决读半包问题,以及通过LineBasedFrameDecoder实例展示了基于行分隔的解码过程,帮助理解解码器的工作原理。
摘要由CSDN通过智能技术生成

前言

在前面,我们介绍了Netty的三大组件:

在这篇文章中,我们将介绍Netty中的通用基类的解码器ByteToMessageDecoder,在大部分的协议解码中,大量的使用了此基类来构造特定的解码器,可以说是大部分的解码器的基石

同时在后面会介绍读半包的问题,并且揭示ByteToMessageDecoder是如何解决半包问题的。

解码器基石

故名思义,ByteToMessageDecoder这个解码器其作用是将Byte数据转换为一个Message可读的消息对象,而具体解码转换成什么对象,由子类决定。

首先,我们来看一下ByteToMessageDecoder这个类的类结构是怎样的
在这里插入图片描述
很简单,其不过是一个ChannelInboundHandler,从上一篇文章 pipeline事件传播机制源码分析 中,我们可以知道,一个Inbound会关心一个read事件(一般来说),那么看看ByteToMessageDecoder中是否有相应方法,验证我们的猜想

public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
   
    ...
}

那么,就以此方法为入口,来分析一下都做了什么工作

public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
   
  // 其只关心ByteBuf的消息的解码
  if (msg instanceof ByteBuf) {
   
    // 存放解码出来的结果的容器
    CodecOutputList out = CodecOutputList.newInstance();
    try {
   
      ByteBuf data = (ByteBuf) msg;
      // cumulation变量是一个可以累加ByteBuf的ByteBuf
      first = cumulation == null;
      // 如果是第一次解码
      if (first) {
   
        // cumulation直接赋值
        cumulation = data;
      } else {
   
        // 如果是第n次,将data加入cumulation
        // 此时cumulation中有没解码完的旧数据和到来的新数据
        cumulation = cumulator.cumulate(ctx.alloc(), cumulation, data);
      }
      // 子类实现具体的解码逻辑
      callDecode(ctx, cumulation, out);
    }
    // ...
    finally {
   
      // cumulation中的数据若被读完,需要被释放
      if (cumulation != null && !cumulation.isReadable()) {
   
        numReads = 0;
        cumulation.release();
        cumulation = null;
      } else if (++ numReads >= discardAfterReads) {
   
        // We did enough reads already try to discard some bytes so we not risk to see a OOME.
        // See https://github.com/netty/netty/issues/4275
        numReads = 0;
        discardSomeReadBytes();
      }

      int size = out.size();
      decodeWasNull = !out.insertSinceRecycled()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值