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.