美文网首页
1 固定长度的粘包和拆包

1 固定长度的粘包和拆包

作者: 程序男保姆 | 来源:发表于2020-05-09 14:20 被阅读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();
      }
    }
    

    相关文章

      网友评论

          本文标题:1 固定长度的粘包和拆包

          本文链接:https://www.haomeiwen.com/subject/iskaghtx.html