固定长度的粘包和拆包
FixedLengthFrameDecoder(2) 将FixedLengthFrameDecoder添加到pipeline中,指定长度为2
/** 1 固定长度拆包 需配合固定长度沾包*/
ch.pipeline().addLast(new FixedLengthFrameDecoder(2));
如果不进行补全
- 客户端发送的数据
# 客户端发送数据
本地发送数据:0 字节长度:1
本地发送数据:01 字节长度:2
本地发送数据:012 字节长度:3
本地发送数据:0123 字节长度:4
本地发送数据:01234 字节长度:5
- 服务端接收的数据
# 服务端接收的数据
00
10
12
01
23
01
23
由此可见 服务端每次按照2个字节进行拆分,
总体接收的数据为 ”00101201230123“ 字节长度为14位,
其中缺失数据“4” 其原因便是bytebuf 中还有一个字节未被读取
- 添加固定长度沾包
FixedLengthFrameEncoder(2) 用于将长度不足20的消息进行补全空格
/** 1 固定长度沾包 需配合固定长度拆包*/
ch.pipeline().addLast(new FixedLengthFrameEncoder(2));
public class FixedLengthFrameEncoder extends MessageToByteEncoder<String> {
private int length;
public FixedLengthFrameEncoder(int length) {
this.length = length;
}
@Override
protected void encode(ChannelHandlerContext ctx, String msg, ByteBuf out)
throws Exception {
// 对于超过指定长度的消息,这里直接抛出异常
if (msg.length() > length) {
throw new UnsupportedOperationException(
"message length is too large, it's limited " + length);
}
// 如果长度不足,则进行补全
if (msg.length() < length) {
msg = addSpace(msg);
}
ctx.writeAndFlush(Unpooled.wrappedBuffer(msg.getBytes()));
}
// 进行空格补全
private String addSpace(String msg) {
StringBuilder builder = new StringBuilder(msg);
for (int i = 0; i < length - msg.length(); i++) {
builder.append(" ");
}
return builder.toString();
}
}
网友评论