使用netty(使用camel)时出现了一个奇怪的错误,我们使用LengthFieldBasedFrameDecoder进行通信,client是来自第三方的套接字程序,我们在服务器端使用netty(camel-netty组件)。
有时会将两条消息“合并”为一条消息,因此即将发布的数据都会出错。
例如:
客户端发送两条消息:
[10] AAAAAAAAAAAAAAAA 和 [10] BBBBBBBBBBBBBBBB
其中[10]是长度字节,AAAAAAAAAA是数据。
但在我们得到的服务器上 [10] AAAAAA [10] BBBBBBBBBBBBBBBBAAAAAAAAAA
似乎第一条消息被第二条消息拆分,因此解码器将数据解释为:
[10] AAAAAA [10] BBBBBBBB
和
BBBBBBBBAAAAAAAAAA .............................................. .....
这样第一条消息的长度正确但数据错误,第二条消息长度为“BB”错误,并获得更长的数据包。
希望我清楚地描述,之前有人见过这个吗?
答案 0 :(得分:2)
听起来你正在用两个线程写同一个流。
答案 1 :(得分:1)
嗯,这被证明是camel-netty组件的“bug”,稍后我将发布一个修复骆驼项目。在此之前,请小心使用camel-netty组件,特别是不要使用不使用@sharable注释标记的编码器/解码器,否则会导致问题,因为状态可能在不同的连接之间共享。
答案 2 :(得分:1)
您的LengthFieldBasedFrameDecoder
是否延伸FrameDecoder
?
是单身还是不单身?
实际上我解决了同样的问题,我同意彼得的观点;
我查看了FrameDecoder
,发现有一个名为“累积”的ChannelBuffer
属性,它将与解码器的所有频道共享。
让我们看一下FrameDecoder.messageReceived
方法:
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
Object m = e.getMessage();
if (!(m instanceof ChannelBuffer)) {
ctx.sendUpstream(e);
return;
}
ChannelBuffer input = (ChannelBuffer) m; // here is the buffer from the channel
if (!input.readable()) {
return;
}
ChannelBuffer cumulation = cumulation(ctx); // here is the buffer wrapped by the FrameDecoder
if (cumulation.readable()) {
cumulation.discardReadBytes();
// where "[10]AAA[10]BBBBB" happens
cumulation.writeBytes(input);
// if code run here,we will get the wrong buffer
callDecode(ctx, e.getChannel(), cumulation, e.getRemoteAddress());
} else {
callDecode(ctx, e.getChannel(), input, e.getRemoteAddress());
if (input.readable()) {
cumulation.writeBytes(input);
}
}
}
我认为使用FrameDecoder的正确方法是将其设为多个。