udp - 未兑现 receiveBufferSize。 UDP 数据包被截断

标签 udp netty truncate datagram socketchannel

网络 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,我希望我能在这里找到帮助。

最佳答案

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

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

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

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();

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

关于udp - 未兑现 receiveBufferSize。 UDP 数据包被截断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28090357/

相关文章:

sockets - LabVIEW中的UDP广播

java堆内存管理内存不足

c# - C#udp广播包未收到

mobile - 使用 TCP 的小数据包不是个好主意吗?使用 UDP 更好

netty - 如果 JVM GC 仍然存在,为什么我们需要手动处理 Netty ByteBuf 的引用计数?

java - 为什么使用 LengthFieldPrepender/LengthFieldBasedFrameDecoder

sql - 将日期截断到会计年度

string - 在设定位置提取字符

java - 将 double 值截断为小数点后 6 位

c++ - 使用UDP协议(protocol)发送数据包