我有一个客户端连接到服务器。 TCP会话中的通信是双向的。如果我尝试同时从服务器向客户端发送多条消息,它们会混合在一个阵列中。到达ByteArrayDecoder时,该消息已损坏。这是我的管道:
ChannelPipeline channelPipeline = ch.pipeline();
channelPipeline.addLast("byteArrayEncoder", new ByteArrayEncoder());
channelPipeline.addLast("myRequestEncoder", new MyRequestEncoder());
channelPipeline.addLast("mySecondEncoder", new MySecondEncoder());
channelPipeline.addLast("byteArraydDecoder", new ByteArrayDecoder());
channelPipeline.addLast("myResponseDecoder", new MyResponseDecoder());
channelPipeline.addLast("mySecondDecoder", new MySecondDecoder());
channelPipeline.addLast("mytHandler", myHandler);
例如,我注意到ByteArrayDecoder中的字节数组的长度超过500而不是230.我已经看到数组的内容对应于两个或多个已连接的消息。
我只有一个频道。我试图在管道中使用多个EventExecutorGroup,但这种情况一直在发生,我最终错过了几个入站消息。
然而,1tps一切似乎都运行正常。
netty应该有这样的行为吗?我错过了什么吗?
答案 0 :(得分:3)
TCP是一种基于流的协议,您的应用程序应该从该概念开始工作。 Netty还从网络层接收字节作为流,并将其作为应用程序的工作转换为有用的字节流。
您无法正确转换应用程序可以处理的正确数据块中的传入流字节。
有多种方法可以为字节引入“reframer”:
如果每个数据包都是固定长度,你可以只读取X
字节数,并将其用作简单的框架解决方案,使用netty非常简单:
channelPipeline.addLast("framer", new FixedLengthFrameDecoder(512));
这会将所有传入的字节以512字节的块分割。
您可以为数据包添加长度,而不是让每个数据包的大小相同,这样您就可以稍后拆分数据包了。 Netty还附带了有用的实用程序类:
channelPipeline.addLast("framer", new LengthFieldBasedFrameDecoder(Short.MAX_VALUE,0,2,0,2));
channelPipeline.addLast("framer-prepender", new LengthFieldPrepender(2, false));
LengthFieldBasedFrameDecoder
的论据是:
LengthFieldPrepender
的论据是: