I got a strange error when using netty(with camel), we use LengthFieldBasedFrameDecoder for communication, client is a socket program from third party, we use netty(camel-netty component) on the server side.
sometimes got two messages "merged" into one, and hence the forthcoming data get all wrong.
for example:
client send two messages:
[10]AAAAAAAAAAAAAAAA and [10]BBBBBBBBBBBBBBBB
where [10] is the length bytes and AAAAAAAAAA is the data.
but on the server we got [10]AAAAAA[10]BBBBBBBBBBBBBBBBAAAAAAAAAA
seems the the first message got split by the second one, so the decoder interpreted the data as:
[10]AAAAAA[10]BBBBBBBB
and
BBBBBBBBAAAAAAAAAA...................................................
so that the first message is correct in length but wrong in data, and the second message is wrong in length "BB", and get a much longer data packet.
hope I described clearly, anyone met this before?
听起来您正在两个线程中写入同一流。
Is your LengthFieldBasedFrameDecoder
extends FrameDecoder
? And is it singleton or not?
Actually I encounted the same problem,and I agree with Peter's point;
I've took a look at the FrameDecoder
,and found that there is a ChannelBuffer
property named "cumulation" ,which will be shared to all Channels of the decoder.
and let's look inside the FrameDecoder.messageReceived
method:
@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);
}
}
}
I think the correct way to use FrameDecoder is make it multcase.
well, this proved to be a "bug" of camel-netty component, I will post a fix to camel project later on. Before that, please be careful using the camel-netty component, especially do not use encoders/decoders not mark with @sharable annotation, it will lead to the problem since state maybe shared among different connections.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.