您好,欢迎来到化拓教育网。
搜索
您的当前位置:首页深入netty08-netty中自带的解码器总结

深入netty08-netty中自带的解码器总结

来源:化拓教育网

定长解码器

FixedLengthFrameDecoder 的工作原理

FixedLengthFrameDecoder 通过构造函数设置期望的消息长度 frameLength。解码器将按照以下步骤工作:

使用 FixedLengthFrameDecoder 的示例

假设我们有一个简单的二进制协议,每个消息恰好为10个字节。我们可以如下方式使用 FixedLengthFrameDecoder


public class CustomFixedLengthFrameDecoder extends FixedLengthFrameDecoder {
    public CustomFixedLengthFrameDecoder() {
        super(10); // 设置固定长度为10
    }
​
    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        // 调用 super.decode() 将自动处理固定长度的拆包
        ByteBuf buf = (ByteBuf) super.decode(ctx, in);
        if (buf != null) {
            // 在这里可以添加额外的处理逻辑,如果需要的话
            return buf; // 将 ByteBuf 作为消息传递给下一个处理程序
        }
        return null;
    }
}

在实际应用中,我们可能需要对解码后的消息进行进一步的处理。例如,我们可以将解码后的消息转换成一个 CustomMessage 对象,而不是直接传递 ByteBuf

public class CustomMessageDecoder extends ByteToMessageDecoder {
    private static final int FRAME_LENGTH = 10;
​
    @Override
    protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
        // 检查是否有足够的数据
        if (in.readableBytes() < FRAME_LENGTH) {
            return;
        }
​
        // 读取固定长度的数据
        ByteBuf buf = in.readBytes(FRAME_LENGTH);
​
        // 将 ByteBuf 转换为自定义消息对象
        CustomMessage message = new CustomMessage(buf.readInt(), buf.readLong());
        out.add(message);
    }
}
​
// CustomMessage 类定义
public class CustomMessage {
    private int field1;
    private long field2;
​
    public CustomMessage(int field1, long field2) {
        this.field1 = field1;
        this.field2 = field2;
    }
​
    // 省略 getter 和 setter 方法
}

分隔符解码器

DelimiterBasedFrameDecoder 是 Netty 提供的另一种强大的解码器,它允许开发者基于特殊分隔符来拆分消息。这种解码器特别适用于文本协议,其中消息通常以换行符、逗号或其他特殊字符分隔。以下是对 DelimiterBasedFrameDecoder 的几个关键属性的详细介绍,以及如何使用这个解码器的示例。

关键属性

  1. delimiters

    • 这是用于消息拆分的特殊分隔符的集合。

    • 类型为 ByteBuf 数组,意味着可以同时指定多个分隔符。

  2. maxLength

    • 这是接收缓冲区中允许的最大字节数,如果超过这个长度还没有检测到分隔符,将抛出 TooLongFrameException

  3. failFast

    • 控制是否在检测到超长消息时立即抛出异常。

    • true 表示立即抛出,false 表示在解码出一个完整消息后抛出。

  4. stripDelimiter

    • 一个布尔值,指示是否从解码后的消息中移除分隔符。

    • 如果设置为 false,则解码的消息将包含分隔符。

示例

假设我们有一个基于换行符 \n 和回车换行 \r\n 结尾的文本协议,我们可以这样使用 DelimiterBasedFrameDecoder

public class CustomDelimiterFrameDecoder extends DelimiterBasedFrameDecoder {
    public CustomDelimiterFrameDecoder() {
        // 指定多个分隔符,这里使用换行符 '\n' 和回车换行 '\r\n'
        super(100, true, Unpooled.copiedBuffer("\n\r\n", CharsetUtil.UTF_8));
    }

    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        ByteBuf buf = (ByteBuf) super.decode(ctx, in);
        if (buf == null) {
            return null;
        }
        
        // 根据需要,这里可以添加额外的处理逻辑
        
        // 返回解码后的消息,这里我们假设它是一个字符串
        return buf.toString(CharsetUtil.UTF_8);
    }
}

长度域解码器

长度域解码器特有属性

  1. lengthFieldOffset

    • 表示长度字段在消息中的起始偏移量。

  2. lengthFieldLength

    • 表示长度字段所占用的字节数。

  3. lengthAdjustment

    • 用于调整消息长度的修正值。当长度域包含了额外的信息(如版本号、数据类型等)时,需要通过这个属性来修正实际的消息长度。

  4. initialBytesToStrip

    • 解码后需要跳过的初始字节数,即去除长度域和可能的其他头部信息。

  5. lengthFieldEndOffset

    • 长度字段结束的偏移量,等于 lengthFieldOffset + lengthFieldLength

与其他解码器相似的属性

  1. maxFrameLength

    • 最大消息长度。

  2. failFast

    • 是否在检测到超长消息时立即抛出 TooLongFrameException

  3. discardingTooLongFrame

    • 是否处于丢弃超长消息模式。

  4. tooLongFrameLength

    • 需要丢弃的字节数。

  5. bytesToDiscard

    • 已累计丢弃的字节数。

示例

假设我们设计了一个简单的二进制协议,其中每个消息的开始是一个4字节的长度字段,后面跟着实际的数据。我们可以这样使用 LengthFieldBasedFrameDecoder

public class CustomLengthFieldBasedFrameDecoder extends LengthFieldBasedFrameDecoder {
    public CustomLengthFieldBasedFrameDecoder() {
        // 长度字段偏移量为0,长度为4字节,不包含任何额外的头部信息,长度无需修正
        super(1024 * 1024, 0, 4, 0, 4);
    }

    @Override
    protected Object decode(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
        ByteBuf buf = (ByteBuf) super.decode(ctx, in);
        if (buf == null) {
            return null;
        }
        // 在这里可以添加额外的处理逻辑,如果需要的话
        return buf;
    }
}

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务