在 Java 中使用 DatagramPacket
假设你有一个 byte[1024*1024]
缓冲区。如果您只是在发送/接收时将其传递给 DatagramPacket,Java 会接收 DatagramPacket 块的调用直到它读取整个兆字节吗?
我在问 Java 是否会将它拆分或只是尝试发送整个被丢弃的东西。
通常 UDP 数据包的大小限制约为 64KB,但我想知道,因为 Java 的 API 允许字节数组,这是否是一个限制,并且一些超大的东西会被丢弃或拆分并为您重新组装。
如果它被丢弃,什么 API 调用会告诉我可以在 Java 调用中使用的最大数据负载?我听说 IPv6 也有巨型帧,但 DatagramPacket(或 DatagramSocket
)是否支持它,因为 UDP 定义了标头规范?
原文由 rbeede 发布,翻译遵循 CC BY-SA 4.0 许可协议
DatagramPacket
只是基于 UDP 的套接字上的包装器,因此适用通常的 UDP 规则。64 KB 是完整 IP 数据报的理论最大大小,但只有 576 字节可以保证被路由。在任何给定的网络路径上,具有最小最大传输单元的链接将决定实际限制。 (1500 字节,较少的标头是常见的最大值,但无法预测会有多少标头,因此将消息限制在 1400 字节左右是最安全的。)
如果超过 MTU 限制,IPv4 会自动将数据报分解成片段并在最后重新组合它们,但最多只能达到 64 KB,并且前提是所有片段都通过。如果任何片段丢失,或者如果任何设备决定它不喜欢片段,那么整个数据包都会丢失。
如上所述,不可能事先知道路径的 MTU 是多少。有多种算法可以通过试验找出答案,但许多设备没有正确执行(或故意忽略)必要的标准,因此一切都归结为反复试验。或者您可以猜测每条消息有 1400 个字节。
至于错误,如果您尝试发送的字节数超过操作系统配置允许的字节数,您应该会收到
EMSGSIZE
错误或类似错误。如果您发送的少于该数量但多于网络允许的数量,则数据包将消失。