netty:protobuf的编码器ProtobufVarint32LengthFieldPrepender()、解码器ProtobufVarint32FrameDecoder()

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010841296/article/details/50957471

首先,下图是常规的netty内置的protibuf编解码器的使用


本文主要介绍下面2个编解码器:

1. ProtobufVarint32LengthFieldPrepender()
对protobuf协议的的消息头上加上一个长度为32的整形字段,用于标志这个消息的长度。
这里是官方举的例子,实际这个字段的长度是5byte



(1)computeRawVarint32Size(final int value)
计算value的大小,二进制每7位为一个单位。


(2)writeRawVarint32(bodyLen)
value值是长度,0x7f的十进制值是127 (00000000 00000000 00000000 01111111),127取反得二进制(11111111 11111111 11111111 10000000) 把value和127取反的二进制进行&运算
1)只要value不大于127,则把长度写为直接写入,并直接返回。
2)如果大于127,则把value与127进行&运算,只取value二进制的低7位为1的值(其它位置0),接着把value与0x80(10000000)进行|运算,把value第8位的值变为1后写入(如果以byte类型读,则恒为负数),只取 128- 255的值。 再把value无符号右移7位,继续下一次循环


2. ProtobufVarint32FrameDecoder()
这是针对protobuf协议的 ProtobufVarint32LengthFieldPrepender()所加的长度属性的解码器
官方例子:


protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
    in.markReaderIndex();
    // 因为length的长度为5个字节,所以申请一个5个字节的数组
    final byte[] buf = new byte[5];
    for (int i = 0; i < buf.length; i ++) {
        //判断是否可读,不可读要重置read的索引
        if (!in.isReadable()) {
            in.resetReaderIndex();
            return;
        }
        //从in里面读取数据放入数组,此时buf[i]的值有两种情况,
        //(1)正数,代表当前数组i的值已经是长度二进制的最高位的值(以8个字节为单位的byte),可以进行读取。
        //(2)负数,代表当前值大于127,所以在编码时与0x80(10000000)做过|运算,所以不能读取,继续进行for循环
        buf[i] = in.readByte();
        if (buf[i] >= 0) {
            int length = CodedInputStream.newInstance(buf, 0, i + 1).readRawVarint32();
            if (length < 0) {
                throw new CorruptedFrameException("negative length: " + length);
            }

            if (in.readableBytes() < length) {
                in.resetReaderIndex();
                return;
            } else {
                out.add(in.readBytes(length));
                return;
            }
        }
    }

    // Couldn't find the byte whose MSB is off.
    throw new CorruptedFrameException("length wider than 32-bit");
}


猜你喜欢

转载自blog.csdn.net/u010841296/article/details/50957471