如何在 Netty Java 中创建 HeapBuffer?

How to create a HeapBuffer in Netty Java?

我在 Java 中使用 Netty 包实现了非常简单的客户端-服务器机器。 当我从客户端向服务器发送大约 1000 条消息时,Netty 创建了一个大小为 1024 的缓冲区,并将消息一个接一个地插入缓冲区并发送到 ServerHandler(在服务器端),后者又将接收到的消息显示在终端上.现在的问题是当缓冲区变满时,缓冲区被发送到服务器并创建一个新缓冲区,消息的剩余字符被插入缓冲区并在缓冲区已满时再次发送。这使得我的消息字符串有时会被截断并发送到服务器。

例如:

当我从客户端向服务器发送"Hello Netty" 1000 次时,缓冲区被一个一个地填满。在特定点,缓冲区已满,显示 "Hello" 作为内部的最后一部分,并被发送到服务器。剩下的部分"Netty"被填入新的缓冲区并发送给服务器。这就像发送半个字符串。我想消除这个。我认为用 Heap Buffer 代替 Unpooled.copiedBuffer(我在下面的代码中实现)可以解决这种情况。是不是写这样做。如果是,如何在 Netty 中实现 HeapBuffer??

客户端处理程序

public void channelActive(ChannelHandlerContext ctx){
      System.out.println("Connected");
      int i=0;
     while(i<10){
        ctx.writeAndFlush(Unpooled.copiedBuffer("8=FIX.4.29=0007935=A49=TTDS68AO56=Min34=152=201704274:05:04.572108=60\n", CharsetUtil.UTF_8)); //created unpooled copiedBuffer. Need to create HeapBuffer
       i++;
    }
}

ServerHandler

public void channelRead(ChannelHandlerContext ctx, Object msg) {
        ByteBuf in = (ByteBuf) msg;
        System.out.println(in.toString(CharsetUtil.UTF_8));
}

示例输出:(仅显示最多 3 次重复)

8=FIX.4.29=0007935=A49=TTDS68AO56=Min34=152=201704274:05:04.572108=60 8=FIX.4.29=0007935=A49=TTDS68AO56=Min34=152=20170427-14:05:04.572108=60 8=FIX.4.29=0007935=A49=TTDS68AO56=Min34=152=20170427
//HALF STRING CAME HERE

14:05:04.572108=60 //THIS NEED TO COME ALONG WITH THE ABOVE STRING,BUT CAME AS NEW STRING

Netty包中还有一个class"UnpooledHeapByteBuf"。但我不知道如何使用它。请问有人可以帮忙吗?

由于Tcp mss,套接字可以通过多个数据包发送一个数据或通过一个发送多个数据packet.So你应该自己拆分或组合数据包。 例如,您可以在数据包中添加一个长度指示数据大小header。当然,Netty 提供了一些处理程序来解决它。

让我们看看下面的代码:

ctx.writeAndFlush(Unpooled.copiedBuffer("abcdefhijk", CharsetUtil.UTF_8));

当你将字节数组发送给另一个时,tcp协议会将其拆分为多个数据包,如下所示:

first packet:"abcdef"
second packet:"hijk"

另一方面,tcp 协议也将多个数据组合成一个数据包:

ctx.writeAndFlush(Unpooled.copiedBuffer("abcdefhijk", CharsetUtil.UTF_8));
ctx.writeAndFlush(Unpooled.copiedBuffer("abcdefhijk", CharsetUtil.UTF_8));

数据包是:

only packet:"abcdefhijkabcdefhijk"

所以接收方应该将这些数据包组合成一个数组或从一个数组中检索一个数组 packet.One 有用的方法是在有人向另一个数据包发送数据时向每个数据包添加一个长度指示数组大小,长度是数组的大小。 LengthFieldPrepender 处理程序可以像这样处理 that.The 数据包:

* +--------+----------------+
* + 0x000A | "abcdefhijk" |
* +--------+----------------+

接收方应该从数据包中读取长度header,长度为0x000A,然后从数据包中读取0x000A字节的数据。LengthFieldBasedFrameDecoder处理程序可以做到。

像这样:

@Override public void initChannel(SocketChannel ch) throws Exception{ ch.pipeline()..addLast(new LengthFieldBasedFrameDecoder(204800, 0, 4, 0, 4)) .addLast(new LengthFieldPrepender(4)).addLast(new EchoClientHandler()); } });

@Override public void initChannel(SocketChannel ch) throws Exception { System.out.println("New client connected: " + ch.localAddress()); ch.pipeline().addLast(new LengthFieldBasedFrameDecoder(204800, 0, 4, 0, 4)).addLast(new LengthFieldPrepender(4)).addLast(new FixMessageDecoder()); } });