【问题标题】:In netty, how we can send string messages with different arbitrary length?在netty中,我们如何发送不同长度的字符串消息?
【发布时间】:2016-07-15 11:07:40
【问题描述】:

我想通过 netty 发送字符串消息。为此,我需要使用 StringDecoder 和编码器,如下所示:

 ch.pipeline().addLast("frameDecoder", new LineBasedFrameDecoder(**maxLength**)); 
                 ch.pipeline().addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));

                 // Encoder
                 ch.pipeline().addLast("stringEncoder", new StringEncoder(CharsetUtil.UTF_8));

这很好,但唯一让我对 maxLengh 感到失望的部分?!我不知道我的字符串消息的最大大小?为什么它需要它,它可以通过分隔符找到字符串或 \r\n 为什么它需要 maxLength?

有没有什么方法可以在不指定长度的情况下发送字符串消息?顺便说一句,如果我将限制设置为很大,并且只使用一小部分,我会丢失任何东西吗?我在浪费空间吗?

我正在编写一个分布式键值存储,我系统中的服务器相互复制新的写入,我不知道一个键的值有多大。

谢谢

【问题讨论】:

  • 当我使用传统的服务器/客户端架构时,我曾经很容易使用 println() 和 readLine() 发送无限行。我希望我也可以使用 netty 来做到这一点。

标签: java netty


【解决方案1】:

凡事有始必有终。如果没有 LF 发送到服务器怎么办?这就是为什么有一个最大长度。我认为在设计这种系统时应该设置行长的限制。

如果你设置一个非常大的数字,并且只接收短行,那么不会浪费空间。

【讨论】:

  • 所以,如果我将代码中的最大长度设置为 1M(字节),是否安全?因为那个我没有腰部空间?
  • 如果只收到短行,是的。 netty 将检查行的长度,然后创建一个大小 == 长度的字节缓冲区对象。
  • 您对我关于逐一搜索“\n”的建议有何评论?我认为这是我们寻找分隔符时唯一的解决方案,所以可能甚至 netty 本身也在 LineBasedFrameDecoder 中使用这种方法。
  • 我建议阅读netty的代码。实际上是的(基于 4.0.36-Final),以更好的方式:)
【解决方案2】:

我发现了另一个可以用于发送字符串的帖子: Netty channel.write not writing message

所以使用那里建议的方法,我想出了这个解决方案,但如果它有效,我就没有。

发送:

 String str = "Hello";
 ctx.writeAndFlush(Unpooled.copiedBuffer(str, CharsetUtil.UTF_8)); // (3)

接收:

我首先在类中定义一个StringBuffer作为成员:

StringBuffer sBuf = new StringBuffer("");

然后在channelRead中我会有:

public void channelRead(ChannelHandlerContext ctx, Object msg) {
    System.out.println("Inside channelRead");
    ByteBuf in = (ByteBuf) msg;
    while (in.isReadable()) {
        byte b = in.readByte();
        char c = (char)b;
        System.out.print(c);
        if (c == '\n') {
            System.out.println("Client received: " + sBuf.toString());
            sBuf = new StringBuffer("");
        } else {

            sBuf.append(c);
        }
    }

    ctx.close();
    in.release();
}

我知道,它看起来效率不高,但是我在这里检查了我以前以传统方式使用的 BufferReader 的 readLine() 方法的 java 代码: http://developer.classpath.org/doc/java/io/BufferedReader-source.html

我认为它正在做同样的事情(我不喜欢)它使用 StringBuffer 和 append 方法,但它看起来很复杂,也许这比我的简单想法更有效:p

那你们觉得呢?我测试了它,它工作正常,唯一关心的是效率。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-13
    • 1970-01-01
    • 1970-01-01
    • 2020-05-23
    • 1970-01-01
    • 2016-01-13
    • 2013-02-06
    • 1970-01-01
    相关资源
    最近更新 更多