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

时间:2016-10-03 13:35:14

标签: java network-programming multicast mtu

我是一名新手,并且在我的网络编程方面有所帮助。我正在通过多播读取数据(参见下面的代码),并希望找到最大传输单位(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();
    }

3 个答案:

答案 0 :(得分:0)

我不确定你的意图是什么,但对于这个答案我会假设你想要获得bb的大小以确保不会截断任何数据包。

MulticastSocket类继承自DatagramSocket。 DatagramSocket有一个getReceiveBufferSize()方法,以字节为单位返回最大套接字接收缓冲区。

答案 1 :(得分:0)

您可以接收的最大数据报受65507(IPv4)或套接字接收缓冲区大小限制,以较低者为准。

MTU是可以发送的最大值,它是发件人的几件事的属性加上如上所述的总体限制65507。它与接收没有任何关系。在实践中,由于知识产权的影响,它可以低至576或534或一些这样的数字。

答案 2 :(得分:0)

什么是MTU

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

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

一般如何查找MTU

RFC 4821是此过程的一个很好的提要。

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

很遗憾,因为这是多播...

RFC 4821的

Section 5.4说,

  

对于多播目标地址,是数据包的副本      可能会穿越许多不同的路径以到达许多不同的节点。的      组播目标的“路径”的本地表示形式必须位于      事实表示可能存在大量路径。

     

至少,实现可以将单个MTU值保持为      用于源自该节点的所有多播数据包。这个MTU      应该足够小,以至于小于      组成多播树的所有路径的路径MTU。如果是路径MTU      通过单播获悉少于配置的多播MTU      意味着多播MTU可以减少到这个值。这种方法      可能会导致使用比必要的更小的数据包      许多路径。

     

如果使用多播的应用程序获得完整的交付报告      (不太可能因为此要求的伸缩性较差),      PLPMTUD可以在多播协议中实现,以便      跨组学习的最小MTU路径成为有效MTU      该组。

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

很遗憾,因为这是Java ...

Java不支持ICMP。完全没有而且实际上不可能通过UDP进行此操作-由于透明的重组,我们不知道何时会发生碎片。

所以我们有两个选择

  • 不必过分担心数据包碎片,但可以为接收方的缓冲区大小声明一个契约。例如,使用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字节)