receiveBufferSize 不被遵守。UDP 数据包被截断

Chr*_*s M 3 udp truncate datagram socketchannel netty

网络 4.0.24

我通过 UDP 传递 XML。当接收到UPD数据包时,数据包的长度始终为2048,从而截断了消息。尽管如此,我尝试将接收缓冲区大小设置为更大的值(4096、8192、65536),但它没有被兑现。

我已经使用另一种 UDP 摄取机制验证了 UDP 发送方。使用 java.net.DatagramSocket 的独立 Java 应用程序。XML 约为 45k。

我能够将堆栈跟踪到 DatagramSocketImpl.createChannel (第 281 行)。进入 DatagramChannelConfig,它的 receiveBufferSize 是我设置的(很好),但 rcvBufAllocator 为 2048。

rcvBufAllocator 是否会覆盖 receiveBufferSize (SO_RCVBUF)?消息是否来自多个缓冲区?

任何反馈或替代解决方案将不胜感激。

我还应该提到,我正在使用一个名为 vert.x 的 ESB,它大量使用 netty。由于我能够追踪到 netty,我希望能在这里找到帮助。

Mik*_*tra 5

从套接字复制出来的传入数据报的最大大小实际上不是套接字选项,而是read()客户端每次想要读取数据报时传入的套接字函数的参数。该接口的优点之一是,接受未知/变化长度的数据报的程序可以自适应地更改为传入数据报副本分配的内存大小,这样它们就不会过度分配内存,同时仍能获取整个数据报。(在 netty 中,这种分配/预测是由 的实现者完成的io.netty.channel.RecvByteBufAllocator。)

相反,SO_RCVBUF是保存客户端尚未读取的所有数据报的缓冲区的大小。

下面是如何使用 netty 4.x 配置具有固定最大传入数据报大小的 UDP 服务的示例Bootstrap

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelOption;
import io.netty.channel.FixedRecvByteBufAllocator;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;

int maxDatagramSize = 4092;
String bindAddr = "0.0.0.0";
int port = 1234;

SimpleChannelInboundHandler<DatagramPacket> handler = . . .;
InetSocketAddress address = new InetSocketAddress(bindAddr, port);
NioEventLoopGroup group = new NioEventLoopGroup();
Bootstrap b = new Bootstrap()
      .group(group)
      .channel(NioDatagramChannel.class)
      .handler(handler);
b.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(maxDatagramSize));
b.bind(address).sync().channel().closeFuture().await();
Run Code Online (Sandbox Code Playgroud)

您还可以使用以下方式配置分配器ChannelConfig.setRecvByteBufAllocator