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

时间:2018-06-25 06:20:24

标签: netty bytebuffer

在我的用例中,我需要在读取或写入之前对每个字节进行异或运算 到网络。因此,我实现了一个双工处理程序。

但是我无法在适当的位置编辑输出字节缓冲区,这很奇怪, 而阅读方面可以:

@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);
}

请注意,write()的msg参数是从{ 它以前的处理程序。

如果我在ByteBuf中编辑bytebuf,则该应用程序无法像 预期的(我不知道会发生什么,如果我将应用程序设为代理程序, 在适当的位置编辑buf,它将不起作用:某些代理连接会 输入错误的内容),因此我必须回退以复制缓冲区进行编辑, 是很慢的方式,对吧?

write()中的字节缓冲区是否有特殊之处?

编辑:

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

入站通道的管道:

write()

出站渠道的管道:

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 个答案:

答案 0 :(得分:1)

通常应该可以将其调整到位。我怀疑您多次写入相同的缓冲区(或共享相同存储的不同缓冲区)时可能会遇到问题。

答案 1 :(得分:1)

我找到了问题。

在我的代码的某些路径中,我- Delete model MyModel是一个静态字节数组,然后执行Unpooled.wrappedBuffer(),因此,如果出站处理程序中的write()直接修改了缓冲区,它将更改字节数组。并影响下一次重用,因此写入网络的内容在一半时间内是错误的。

因此解决方案是复制字节数组:

write()

顺便说一句,正确修改缓冲区的正确方法是什么? ByteBuf buf = ctx.alloc().buffer(src.length); buf.writeBytes(src); 应该使用setByte()作为偏移量吗?

readerIndex