Netty源码分析系列之常用解码器(上)

本文分析了Netty中的FixedLengthFrameDecoder、LineBaseFrameDecoder和DelimiterBasedFrameDecoder三种常用解码器的工作原理。FixedLengthFrameDecoder基于固定长度解码,LineBaseFrameDecoder基于行分割符解码,DelimiterBasedFrameDecoder允许用户自定义分隔符解码。每个解码器在处理数据时考虑了数据长度限制和丢弃模式,确保有效解码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

扫描下方二维码或者微信搜索公众号菜鸟飞呀飞,即可关注微信公众号,阅读更多Spring源码分析Java并发编程文章。

微信公众号

前言

在上一篇文章中,只分析了 netty 如何通过编解码器解决了 TCP 粘包、半包的问题,没有具体分析解码器是如何来对数据进行解码的,今天本文将具体分析这些解码器的工作原理。

netty 为我们提供了几个十分常用的解码器,这几个解码器几乎能满足我们所有的场景,这几个解码器根据难易程度,从上到下,如下表所示。

FixedLengthFrameDecoder(基于固定长度的解码器)
LineBasedFrameDecoder (基于行分隔符的解码器)
DelimiterBasedFrameDecoder (基于自定义分割符的解码器)
LengthFieldBasedFrameDecoder (基于长度字段的解码器)

前三个解码器比较简单,也容易理解,最后一个解码器相对而言比较复杂,也不容易理解,但它能满足的场景却是最多的。由于前三个解码器比较简单,因此将它们的源码放在一篇文章中分析,也就是今天本文的主要内容。最后一个解码器的源码将在后面一篇文章中单独分析。

FixedLengthFrameDecoder

根据类名,翻译过来就能知道这是一个基于固定长度的解码器,什么意思呢?就是在初始化这个解码器时,指定一个 int 类型的数值:frameLength,后面在解码时,每当读到 frameLength 长度的字节时,就解码出一个数据对象。例如:当发送方发送了四次数据,分别是 A、BC、DEFG、HI,一共 9 个字节,如果我们指定解码器的固定长度 frameLength = 3,那么就表示每 3 个字节解一次码,那么解码出来的结果结果就是:ABCDEFGHI

+---+----+------+----+          +-----+-----+-----+
| A | BC | DEFG | HI |   ->    | ABC | DEF | GHI |
+---+----+------+----+          +-----+-----+-----+

基于固定长度的解码器的源码和注释如下,比较简答,就不做展开分析了,参考源码中的注释即可。

public class FixedLengthFrameDecoder extends ByteToMessageDecoder {
   

    // 表示每次解码多长的数据
    private final int frameLength;

    public FixedLengthFrameDecoder(int frameLength) {
   
        checkPositive(frameLength, "frameLength");
        // 指定每次解码的字节数
        this.frameLength = frameLength;
    }

    @Override
    protected final void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
   
        // 解码
        Object decoded = decode(ctx, in);
        // 如果解码出来的数据对象不为空,就将其保存到out这个集合中
        if (decoded != null) {
   
            out.add(decoded);
        }
    }

    protected Object decode(
            @SuppressWarnings("UnusedParameters") ChannelHandlerContext ctx, ByteBuf in) throws Exception {
   
        // 如果可读取的数据小于每次解码的长度,那就直接返回null
        if (in.readableBytes() < frameLength) {
   
            return null;
        } else {
   
            // 读取指定长度的字节数据,然后返回
            return in.readRetainedSlice(frameLength);
        }
    }
}

LineBaseFrameDecoder

LineBaseFrameDecoder是基于行分割符的解码器。什么意思呢?就是每当读到行分隔符(\n 或者\r\n)的时候,就解析出一个数据对象。例如如下示例。

+---+-------+----------+------+          +-----+-----+</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值