这两个类通常一起使用来解决半包与粘包的问题
LengthFieldPrepender编码器
作用:将当前发送消息的二进制字节长度,添加到缓冲区头部;这样消息就有了固定长度,长度存储在缓冲头中
构造方法
public LengthFieldPrepender(int lengthFieldLength, boolean lengthIncludesLengthFieldLength) {
this(lengthFieldLength, 0, lengthIncludesLengthFieldLength);
}
lengthFieldLength 长度字段长度
lengthIncludesLengthFieldLength 长度字段是否包含长度字段长度
听起来绕口,举个例子
new LengthFieldPrepender(4, false)
上面的意思是:我用四个字节长度去存储当前发送消息的二进制字节长度,并且这四个字节不算在长度中。
如果发送的消息是“hello ,world”,二进制字节长度12byte,编码后则缓冲头部的4个字节存储的是12
new LengthFieldPrepender(4, true)
上面的意思是:我用四个字节长度去存储当前发送消息的二进制字节长度,并且这四个字节算在长度中。
如果发送的消息是“hello ,world”,二进制字节长度12byte,编码后则缓冲头部的的4个字节存储的是12(消息字节)+4(头部长度字节)
贴上netty权威指南
LengthFieldBasedFrameDecoder半包解码器
如果消息是通过长度进行区分(LengthFieldPrepender)此解码器可以处理粘包与半包问题
其构造方法如下
public LengthFieldBasedFrameDecoder(
int maxFrameLength,
int lengthFieldOffset, int lengthFieldLength,
int lengthAdjustment, int initialBytesToStrip) {
this(
maxFrameLength,
lengthFieldOffset, lengthFieldLength, lengthAdjustment,
initialBytesToStrip, true);
}
共有5个参数
maxFrameLength:消息最大长度,超过会报错
lengthFieldOffset:长度字段偏移量
lengthFieldLength:长度字段长度
lengthAdjustment:要添加到长度字段值的补偿值
initialBytesToStrip:从解码帧中删除的第一个字节数
如下代码表示:消息头只有一个长度字段表示消息长度,占4个字节(从0到4,前两个参数);在解码的时候删除消息长度的4个字节(从0到4,后两个参数)只留下消息内容。
new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4)
如下代码表示:消息头只有一个长度字段表示消息长度,占4个字节(从0到4,前两个参数);在解码的时候会把消息原封不动解码,解码后的消息包括消息头长度字段和消息体(从0到0,表示不删除任何字节,所以包含头部的4个字节和消息体的字节数)。
new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 0)