1 固定长度的粘包和拆包

2020-05-09  本文已影响0人  程序男保姆

固定长度的粘包和拆包

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();
  }
}
上一篇下一篇

猜你喜欢

热点阅读