gpt4 book ai didi

java - 如何测量读取多播时从服务器接收到的数据包最大传输单元 (MTU)

转载 作者:太空宇宙 更新时间:2023-11-04 12:11:18 25 4
gpt4 key购买 nike

我是一名新手,正在尝试一些网络编程。我正在通过多播读取数据(请参见下面的代码),并且想要找到最大传输单元(MTU)或我可以读取的传输单元。任何人都可以指导我找到来源或方法来做到这一点。谢谢。

  try {
InetAddress add = InetAddress.getByName("127.0.0.1");

MulticastSocket socket = new MulticastSocket(1234);
socket.joinGroup(add);

byte[] bb = new byte[2500];

while (true) {

DatagramPacket data = new DatagramPacket(bb, bb.length);
datagramSocket.receive(data);
processDataReceived(bb);
}

datagramSocket.leaveGroup(socket);
}
catch (IOException e) {
e.printStackTrace();
}

最佳答案

什么是 MTU

最大传输单元是数据包的最大大小,在其传输的整个路径上绝对不会被分段。请注意,正如 flakes 提到的,这种碎片通常会透明地发生,即使是通过 UDP!因此,即使您大大超出了路径 MTU,您的数据包也可能会安全地重新组装到达。

因此,MTU 主要是一种降低中间节点传输开销的工具,并可能降低因保留数据包以进行重组时最慢的部分而产生的延迟。

一般如何查找 MTU

RFC 4821是这个过程的一个非常好的概要。

简而言之:发送带有“不分段”标志和一些垃圾填充数据的 ICMP ping。监听 ICMP“数据包太大”消息。如果收到 ping 回复,请使用更大的 ping 数据包重新发送。如果收到“数据包太大”,请使用较小的 ping 重新发送。通过这种方式,您可以对实际 MTU 进行二进制搜索。

不幸的是,因为这是多播...

Section 5.4 RFC 4821 说,

In the case of a multicast destination address, copies of a packetmay traverse many different paths to reach many different nodes. Thelocal representation of the "path" to a multicast destination must infact represent a potentially large set of paths.

Minimally, an implementation MAY maintain a single MTU value to beused for all multicast packets originated from the node. This MTUSHOULD be sufficiently small that it is expected to be less than thePath MTU of all paths comprising the multicast tree. If a Path MTUof less than the configured multicast MTU is learned via unicastmeans, the multicast MTU MAY be reduced to this value. This approachis likely to result in the use of smaller packets than is necessaryfor many paths.

If the application using multicast gets complete delivery reports(unlikely since this requirement has poor scaling properties),PLPMTUD MAY be implemented in multicast protocols such that thesmallest path MTU learned across a group becomes the effective MTUfor that group.

因此,为多播用户找到 MTU 可能不太可行。

不幸的是,因为这是 Java...

Java 不支持 ICMP。完全没有。而且实际上不可能通过 UDP 来做到这一点 - 由于透明的重组,我们永远不知道碎片何时发生。

所以我们有两个选择

  • 不要太担心数据包碎片,但声明接收者缓冲区大小的契约(Contract)。例如,使用 RUDP,每一方在连接开始时声明其接收缓冲区大小,并且发送方在任何发送的数据包中不得超过该大小。
  • 对 MTU 做出最悲观、最糟糕的估计。所有 IPv4 硬件必须传输不分段的 68 字节数据包(根据 RFC 791),或经过重组的 576 字节数据包(根据 RFC 1122)。所有 IPv6 硬件必须传输 1280 字节的数据包而不进行分段(根据 RFC 2460),并且只有源节点可以对 IPv6 中的数据包进行分段(!),因此,如果您自己的主机没有对其进行分段,那就很好。

TL、DR;我可能会分别选择 576/1280 来支持 IPv4/IPv6。

(注:IPv4 UDP 数据包减去 68 字节,IPv6 UDP 数据包减去 48 字节)

关于java - 如何测量读取多播时从服务器接收到的数据包最大传输单元 (MTU),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39832976/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com