Netty channelRead 没有收到完整消息

Netty channelRead not getting full message

为什么 channelRead() 没有给我发送到服务器的完整消息?当消息超过 140 字节(大致上,有时多有时少)时,有时会发生碎片。我正在使用 NioServerSocketChannel class.

的 TCP 套接字

我正在使用 4.1.0.Beta5。

有没有办法在邮件到达时阅读完整的邮件?

this.serverBootstrap = new ServerBootstrap();
this.serverBootstrap.group(new NioEventLoopGroup(1), new NioEventLoopGroup(6))
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<SocketChannel>()
                {
                    @Override
                    public void initChannel(SocketChannel ch) throws Exception
                    {
                        ch.pipeline().addLast(new TestServerHandler());
                    }
                })
                .option(ChannelOption.SO_BACKLOG, (int)Short.MAX_VALUE)
                .option(ChannelOption.SO_RCVBUF, (int) Short.MAX_VALUE)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .option(ChannelOption.TCP_NODELAY, true);
this.serverBootstrap.bind(this.host, this.port);

并且class TestServerHandler 扩展了 ChannelInboundHandlerAdapter:

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {

        String s = buffer.toString(CharsetUtil.UTF_8);

        for(int i = 0; i < 20; i++)
        {
            s = s.replace("[" + ((char)i) + "]", i + "");
        }

        System.out.println(s.length() + "");
        System.out.println();
        System.out.println();
        System.out.println(s);
}

我需要一种方法来获取完整的 bytebuf / bytearray 并在它完全到达服务器时得到通知,以便我的应用程序可以根据客户端发送的数据以正确的方式响应。

简而言之:如何防止碎片并让 channelRead 事件输出整个消息/bytebuf。

TCP 提供字节流,因此您不能依赖于在一个数据包中接收完整的消息。您将需要在您的管道中有一个处理程序,它知道您的消息是如何构建的。 Netty 提供了一些内置的处理程序,您可以根据您的协议进行调整。请参阅《Netty 用户指南》中的 Dealing with a Stream-based Transport

Netty使用的基本数据类型是Channel Buffers或ByteBuf。这只是字节的集合,没有别的。在您的代码中,您只是使用自定义处理程序来处理原始传入数据。这通常不是一个好的做法。一个非常基本的 netty 管道应该如下所示

所以管道由解码器/编码器组成,然后我们有自定义处理程序或日志记录处理程序。我们从未真正按原样处理任何原始数据。 TCP是一种流协议。它不识别特定数据包何时结束以及新数据包何时开始。即使我们发送一个非常非常大的数据包或者说两个单独的数据包,它们也会被简单地视为一组字节,当我们尝试读取原始字节集时,可能会发生碎片 .

因此正确实施由字符串解码器/编码器(无论您需要什么)组成的通道管道,这个问题就会消失。