【问题标题】:Dealing with fragmentation in Netty在 Netty 中处理碎片
【发布时间】:2012-01-19 14:22:39
【问题描述】:

我正在使用 Netty 设计一个用于客户端/服务器通信的二进制协议,发送的字节数不是固定的,可以是任意大小。

客户端发送如下内容:

前4个字节代表一个id号 剩下的字节是一个字符串

在我看到的示例中,消息的大小是固定的,但字符串内容可以是任意大小,并且需要确保它在被服务器接收时没有碎片。我将如何在 Netty 中实现这一点?

提前致谢。

【问题讨论】:

    标签: java netty


    【解决方案1】:

    您如何确定消息的结尾?零?我会查看 Netty 重放解码器:

    http://docs.jboss.org/netty/3.2/api/org/jboss/netty/handler/codec/replay/ReplayingDecoder.html

    它使您的事情变得容易。继续阅读,直到找到零。如果在达到零之前用完字节,则会抛出异常以退出解码方法。当有更多字节可用时,将再次调用 decode 方法,并将现有字节和新字节组合在一个 ChannelBuffer 中。

    这个循环可以重复,直到你在 ChannelBuffer 中有整个消息......然后你可以传递到下一层进行处理。

    如果可以更改您的协议,我会添加一个长度,因为能够读取长度比检查每个字节是否为零更有效。

    【讨论】:

    • 您好 Gareth,感谢您的回答 - 非常感谢。我目前没有使用任何东西来确定消息的结束。一旦我通过调用 buffer.readLong() 来检索 id,我就会调用 buffer.toString(String charsetName) - 这并不理想。当您提到发送有效载荷的大小时,您是否建议将其添加到开头并等待直到收到长度,并使用该任意数字来确定在服务器上等待更多字节?
    • 是的。一旦你有了一个长度,你就可以改用 LengthFieldBasedFrameDecoder(如果你的消息可能非常大,尽管最好基于 SimpleChannelUpstreamHandler 编写你自己的,这样缓冲区只分配一次)。
    【解决方案2】:

    或者,如果它基于行,您可以只使用 DelimiterBasedFrameDecoder 来完成这项工作。

    见: http://netty.io/docs/stable/api/org/jboss/netty/handler/codec/frame/DelimiterBasedFrameDecoder.html

    【讨论】:

    • 谢谢!看起来我需要创建自己的 FrameDecoder 实现。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 2017-12-09
    • 2014-04-09
    • 2021-10-28
    • 2013-04-20
    • 2021-01-31
    相关资源
    最近更新 更多