Java DatagramPacket(UDP)最大发送/ recv缓冲区大小

时间:2012-02-08 23:49:32

标签: java udp

在Java中使用DatagramPacket时假设您有一个byte[1024*1024]缓冲区。如果你只是在发送/接收时为DatagramPacket传递它,那么Java接收对DatagramPacket块的调用,直到它读取整个兆字节为止?

我询问Java是否会将其拆分,或者只是尝试发送丢弃的整个内容。

正常情况下,UDP数据包的大小限制大约是64KB,但我想知道,因为Java的API允许字节数组,如果这是一个限制,那么超大的东西会被丢弃或拆分并重新组装给你。

如果它被删除了什么API调用会告诉我可以在Java调用中使用的最大数据有效负载?我听说IPv6也有巨型帧,但DatagramPacket(或DatagramSocket)是否支持,因为UDP定义了头规格?

2 个答案:

答案 0 :(得分:26)

DatagramPacket只是基于UDP的套接字的包装器,因此适用通常的UDP规则。

64千字节是完整IP数据报的理论最大大小,但保证仅路由576个字节。在任何给定的网络路径上,具有最小最大传输单元的链路将确定实际限制。 (1500字节,更少的标头是常见的最大值,但是不可能预测会有多少标头,因此最安全地将消息限制在大约1400字节。)

如果超过MTU限制,IPv4将自动将数据报分解为片段并在最后重新组合它们,但最多只能达到64千字节,并且只有当所有片段都通过时才会重新组装。如果任何片段丢失,或者任何设备决定它不喜欢片段,那么整个数据包都会丢失。

如上所述,事先不可能知道路径的MTU是多少。有各种算法可供试验,但许多设备没有正确实施(或故意忽略)必要的标准,所以这一切都归结为试验和错误。或者你可以猜测每条消息1400字节。

对于错误,如果您尝试发送的字节数超过操作系统配置为允许的字节数,则应该出现EMSGSIZE错误或其等效错误。如果发送的数量少于网络允许的数量,则数据包将会消失。

答案 1 :(得分:-1)

@ Mihai Danila。因为我无法在上面的答案中添加评论,所以这就是写入回复部分的原因。

继续你对MTU大小的回答,在我的实践中,我尝试使用NetworkInterface.getMTU()-40来设置DatagramSocket.setSendBufferSize()的缓冲区大小。因此,尽量不要依赖getSendBufferSize()这是为了确保它在不同平台上匹配不同的窗口大小,并且在以太网上普遍可以接受(暂时忽略拨号)。我没有硬编码到1460字节(1500-20-20),因为在Windows上,MTU大小普遍为1500.但是,Windows平台自己的窗口大小是8192字节,但我相信,通过将SO_SNDBUF设置为< MTU,我减少了网络/ IP层的负担,以及路由器和接收器的所有跳数,一些开销。因此,减少了网络上的一些延迟。

同样,对于接收缓冲区,我使用的最大值为64K或65535字节。这样我的程序可以使用不同的窗口大小在不同平台上移植。

你认为听起来不错吗?我没有实现任何工具来衡量任何差异,但假设它的情况基于那里的东西。