代码之家  ›  专栏  ›  技术社区  ›  kingluo

netty:如何在适当的位置编辑bytebuf的后端数组?

  •  0
  • kingluo  · 技术社区  · 6 年前

    在我的用例中,我需要在读或写之前对每个字节执行异或运算。 到网络。所以我实现了一个双工处理程序来完成这项工作。

    但奇怪的是我不能在适当的地方编辑bytebuf的输出, 而阅读方可以:

    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        ByteBuf buf = (ByteBuf) msg;
        ByteBuf res = buf.alloc().buffer(buf.readableBytes());
        buf.forEachByte(value -> {
            res.writeByte(value ^ cookie);
            return true;
        });
        buf.release();
        super.write(ctx, res, promise);
    }
    
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf = (ByteBuf) msg;
        buf.forEachByte(new ByteProcessor() {
            private int i = 0;
    
            @Override
            public boolean process(byte value) throws Exception {
                buf.setByte(i++, value ^ cookie);
                return true;
            }
        });
        super.channelRead(ctx, msg);
    }
    

    注意的msg参数 write() 确保 ByteBuf 键入发件人 它的前一个处理程序。

    如果我在 写入() ,应用程序无法作为 预期(我不知道会发生什么,如果我 在适当的位置编辑buf,它将不工作:一些代理连接将 给出错误的内容),所以我必须回退以复制要编辑的缓冲区, 哪种方式比较慢,对吧?

    比特布夫有什么特别的地方吗 写入() 是吗?

    编辑:

    代理服务器成对处理两个通道,入站通道和出站通道,以及它们之间的代理数据。

    入站通道管线:

    ch.pipeline().addLast("ReadTimeoutHandler", new ReadTimeoutHandler(30));
    ch.pipeline().addLast("WriteTimeoutHandler", new WriteTimeoutHandler(30));
    cookie.ifPresent(c -> ch.pipeline().addLast(new FuzzHandler(c)));
    ch.pipeline().addLast(new CopyHandler());
    

    出站通道管线:

    ch.pipeline().addLast(new CopyHandler());
    

    这个 CopyHandler 写入() 成对的通道彼此相连。

    2 回复  |  直到 6 年前
        1
  •  1
  •   Norman Maurer    6 年前

    一般来说,应该可以就地调整。我怀疑您可能会将问题视为多次写入同一个缓冲区(或共享同一存储的不同缓冲区)。

        2
  •  1
  •   kingluo    6 年前

    在我的代码中,我 Unpooled.wrappedBuffer() write() ,所以如果

    所以解决方案是复制字节数组:

    ByteBuf buf = ctx.alloc().buffer(src.length);
    buf.writeBytes(src);
    

    setByte() readerIndex 作为补偿?

    ByteBuf buf = (ByteBuf) msg;
    final int readerIndex = buf.readerIndex();
    buf.forEachByte(new ByteProcessor() {
        private int i = 0;
    
        @Override
        public boolean process(byte value) throws Exception {
            buf.setByte(readerIndex + i, value ^ cookie);
            i++;
            return true;
        }
    });