Netty 连接同时到达的消息

Netty concatenates messages that arrive simultaneously

我有一个连接到服务器的客户端。 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应该有这样的行为吗?我错过了什么吗?

TCP 是一种基于流的协议,您的应用程序应遵循该概念。 Netty 还从网络层接收字节流,应用程序的工作是将字节流转换为有用的东西。

您未能将传入的流字节正确转换为您的应用程序可以处理的正确数据块。

有多种方法可以为字节引入 "reframer":

让每个数据包固定长度

如果每个数据包都是固定长度,您可以只读取 X 个字节,并将其用作简单的成帧解决方案,这使用 netty 非常简单:

channelPipeline.addLast("framer", new FixedLengthFrameDecoder(512));

这会将所有传入字节拆分为 512 字节的块。

FixedLengthFrameDecoder 的参数是:

  • 传入数据包的长度

发送前添加数据包的长度

除了让每个数据包大小相同之外,您还可以为数据包添加一个长度,以便稍后拆分数据包。 Netty 还为此提供了有用的实用程序 类:

channelPipeline.addLast("framer", new LengthFieldBasedFrameDecoder(Short.MAX_VALUE,0,2,0,2));
channelPipeline.addLast("framer-prepender", new LengthFieldPrepender(2, false));

LengthFieldBasedFrameDecoder 的参数是:

  • 最大帧长度
  • 帧长度接收数据偏移量
  • 长度字段的字节长度
  • 要从收到的消息中剥离的字节数

LengthFieldPrepender 的参数是:

  • 长度字段的字节长度