在我的用例中,我需要在读取或写入之前对每个字节进行异或运算 到网络。因此,我实现了一个双工处理程序。
但是我无法在适当的位置编辑输出字节缓冲区,这很奇怪, 而阅读方面可以:
@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
彼此配对的频道。
答案 0 :(得分:1)
通常应该可以将其调整到位。我怀疑您多次写入相同的缓冲区(或共享相同存储的不同缓冲区)时可能会遇到问题。
答案 1 :(得分:1)
我找到了问题。
在我的代码的某些路径中,我- Delete model MyModel
是一个静态字节数组,然后执行Unpooled.wrappedBuffer()
,因此,如果出站处理程序中的write()
直接修改了缓冲区,它将更改字节数组。并影响下一次重用,因此写入网络的内容在一半时间内是错误的。
因此解决方案是复制字节数组:
write()
顺便说一句,正确修改缓冲区的正确方法是什么? ByteBuf buf = ctx.alloc().buffer(src.length);
buf.writeBytes(src);
应该使用setByte()
作为偏移量吗?
readerIndex