设计协议时,虽然我们可以定义如何解析每一个完整的数据包,但是无法保证每次收到的数据包都是完整的。如果出现粘包或半包的问题,就会导致自定义的解析器出错,这就需要Netty提供的如下帧解析器来处理。
// 帧解析器,参数分别表示帧大小,帧内容长度字段的起始偏移,帧内容长度字段本身的长度,内容相比长度字段的偏移量,解析后需要从首部剔除的字节数
// 当发生半包时,帧解析器发现没有获取到完整的帧,就不会把收到的数据向下一个handler传递,知道收到完整的帧才会传递,这就保证了帧的完整性。
public LengthFieldBasedFrameDecoder(
int maxFrameLength,
int lengthFieldOffset, int lengthFieldLength,
int lengthAdjustment, int initialBytesToStrip)
复制
lengthFieldOffset = 0 lengthFieldLength = 2 lengthAdjustment = 0 initialBytesToStrip = 0 (= do not strip header) BEFORE DECODE (14 bytes) AFTER DECODE (14 bytes) +--------+----------------+ +--------+----------------+ | Length | Actual Content |----->| Length | Actual Content | | 0x000C | "HELLO, WORLD" | | 0x000C | "HELLO, WORLD" | +--------+----------------+ +--------+----------------+ lengthFieldOffset = 1 (= the length of HDR1) lengthFieldLength = 2 lengthAdjustment = 1 (= the length of HDR2) initialBytesToStrip = 3 (= the length of HDR1 + LEN) BEFORE DECODE (16 bytes) AFTER DECODE (13 bytes) +------+--------+------+----------------+ +------+----------------+ | HDR1 | Length | HDR2 | Actual Content |----->| HDR2 | Actual Content | | 0xCA | 0x000C | 0xFE | "HELLO, WORLD" | | 0xFE | "HELLO, WORLD" | +------+--------+------+----------------+ +------+----------------+
复制