zoukankan      html  css  js  c++  java
  • Netty源码分析第6章(解码器)---->第2节: 固定长度解码器

     

    Netty源码分析第六章: 解码器

     

    第二节: 固定长度解码器

     

    上一小节我们了解到, 解码器需要继承ByteToMessageDecoder, 并重写decode方法, 将解析出来的对象放入集合中集合, ByteToMessageDecoder中可以将解析出来的对象向下进行传播, 这一小节带大家剖析一个最简单的解码器FixedLengthFrameDecoder, 从它入手了解码器的相关原理

    FixedLengthFrameDecoder是一个固定长度的解码器, 功能就是根据固定长度, 截取固定大小的字节数进行解码

    看其类的定义:

    public class FixedLengthFrameDecoder extends ByteToMessageDecoder {
        //长度大小
        private final int frameLength;
        public FixedLengthFrameDecoder(int frameLength) {
            if (frameLength <= 0) {
                throw new IllegalArgumentException(
                        "frameLength must be a positive integer: " + frameLength);
            }
            //保存当前frameLength
            this.frameLength = frameLength;
        }
        @Override
        protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
            //通过ByteBuf去解码.解码到对象之后添加到out上
            Object decoded = decode(ctx, in);
            if (decoded != null) {
                //将解析到byteBuf添加到对象里面
                out.add(decoded);
            }
        }
        protected Object decode(
                @SuppressWarnings("UnusedParameters") ChannelHandlerContext ctx, ByteBuf in) throws Exception {
            //字节是否小于这个固定长度
            if (in.readableBytes() < frameLength) {
                return null;
            } else {
                //当前累加器中截取这个长度的数值
                return in.readRetainedSlice(frameLength);
            }
        }
    }

    我们看到这个类继承了ByteToMessageDecoder, 重写了decode方法

    这个类只有一个属性叫frameLength, 并在构造方法中初始化了该属性

    再看decode方法, 在decode方法中又调用了自身另一个重载的decode方法进行解析, 解析出来之后将解析后的数据放在集合out中

    再看重载的decode方法:

    重载的decode方法中首先判断累加器的字节数是否小于固定长度, 如果小于固定长度则返回null, 代表不是一个完整的数据包, 直接返回null

    如果大于等于固定长度, 则直接从累加器中截取这个长度的数值

     in.readRetainedSlice(frameLength) 会返回一个新的截取后的ByteBuf, 并将原来的累加器读指针后移frameLength个字节

    如果累计器中还有数据, 则会通过ByteToMessageDecoder中callDecode方法里while循环的方式, 继续进行解码

    这样, 就是实现了固定长度的解码工作

     

    上一节: ByteToMessageDecoder

    下一节: 行解码器

  • 相关阅读:
    面试技巧
    JDK1.8新特性(一): 接口的默认方法default
    idea2019.2安裝MybatisCodeHelper插件
    为什么要拆掉“烟囱式”系统
    git
    springboot-使用AOP日志拦截实现
    为何放弃Eclipse,选择IntelliJ IDEA,看完终于明白了
    StringUtils.isBlank()的使用
    count(1)、count(*)、count(字段)的区别
    关于redis中zset底层跳表的理解
  • 原文地址:https://www.cnblogs.com/xiangnan6122/p/10206405.html
Copyright © 2011-2022 走看看