netty LengthFieldBasedFrameDecoder 自定义长度帧解码器

阅读数:91 评论数:0

跳转到新版页面

分类

python/Java

正文

一、概述

一个Netty的ByteBuf包,可以被TCP拆分成多个二进制数据帧进行发送,也有可能,底层将多个小的ByteBuf包,封装成一个大的底层数据帧发送出去。

如何从底层的二进制数据帧中,界定出上层数据包的边界?这就是Netty中帧解码器的作用。

二、LineBasedFrameDecoder

行分割帧解码器。

适用场景:每个上层数据包,使用换行符或者回车换行符做为边界分割符。发送端发送的时候,每个数据包之间以换行符/回车换行符作为分隔。在这种场景下,只需要把这个解码器加到 pipeline 中,Netty 会使用换行分隔符,把底层帧分割成一个一个完整的应用层数据包,发送到下一站。

三、FixedLengthFrameDecoder

固定长度帧解码器。

适应场景:每个上层数据包的长度,都是固定的,比如 100。在这种场景下,只需要把这个解码器加到 pipeline 中,Netty 会把底层帧,拆分成一个个长度为 100 的数据包 (ByteBuf),发送到下一个 channelHandler入站处理器。

四、DelimiterBasedFrameDecoder

自定义分隔符帧解码器。

DelimiterBasedFrameDecoder 是LineBasedFrameDecoder的通用版本。不同之处在于,这个解码器,可以自定义分隔符,而不是局限于换行符。如果使用这个解码器,在发送的时候,末尾必须带上对应的分隔符。

五、LengthFieldBasedFrameDecoder

自定义长度帧解码器。

在数据包中,加了一个长度字段(长度域),保存上层包的长度。解码的时候,会按照这个长度,进行上层ByteBuf应用包的提取。

它涉及5个参数:

maxFrameLength 发送的数据包最大长度
lengthFieldOffset 长度域偏移量,指的是长度域位于整个数据包字节数组中的下标
lengthFieldLength

长度域的自己的字节数长度

lengthFieldLength的取值不是任意的, 它只能取值1,2,3,4,8

里面的内容作为真正data的长度

lengthAdjustment

真正数据data的长度, 必须用lengthFieldLength的内容值+lengthAdjustment的值.

initialBytesToStrip

丢弃的起始字节数。丢弃处于有效数据前面的字节数量。

从最左边开始读取数据, lengthFieldOffset=1, 那么向后读取1个字节, lengthFieldLength=2, 向后读取2个字节, 读取到的内容是0x0010(十六进制), 十进制就是16, 由于lengthAdjustment=-3, 因此16+(-3)=13, 于是继续向后读取13个字节. 就会把0xFE和"HELLO, WORLD"这13个字节读取到. 到目前为止, 读取到的内容是0xCA0010FE和"HELLO, WORLD"共16个字节. 又initialBytesToStrip=3, 因此从16个字节的开头跳过3个字节,  跳过了0xCA0010这3个字节, 最后剩下0xFE和"HELLO, WORLD"传给了下游的Handler.




相关推荐

LineBasedFrameDecoder以换行符\n或\r\n作为依据,遇到\r\n都认为是一条完整的消息。 而DelimiterBasedFrameDecoder允许我们指定任