【问题标题】:How much data can I send in one UDP packet and still avoid fragmentation?我可以在一个 UDP 数据包中发送多少数据并且仍然避免碎片?
【发布时间】:2018-06-05 07:54:11
【问题描述】:

我有处理发送和接收 UDP 数据包的 C++ 类。到目前为止,我使用它们来发送信号(PING、WAKEUP、...),换句话说,是非常小的数据包,从来没有出现过问题。

现在我想发送大块数据(即 0.5Mb),但为了优化丢包的可能性,我希望能够自己进行分段。首先我写了一个函数,它给了我 MTU 大小:

int udp_server::get_mtu_size() const
{
    if(f_mtu_size == 0)
    {
        struct ifreq ifr;
        memset(&ifr, 0, sizeof(ifr));
        strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name));
        if(ioctl(f_socket, SIOCGIFMTU, &ifr) == 0)
        {
            f_mtu_size = ifr.ifr_mtu;
        }
        else
        {
            f_mtu_size = -1;
        }
    }

    return f_mtu_size;
}

注意:我知道这个函数忽略的 PMTUD。如下所述,这是为了在受控网络上工作,因此 MTU 路径不会仅仅在我们身上改变。

这个函数在Linux下很可能返回1500。

真正不清楚并且在许多答案之间似乎相互矛盾的是,这 1,500 字节的大小不仅仅是我的有效负载。它可能包括一些我无法控制的标头(即以太网标头 + 页脚、IPv4 标头、UDP 标头。)

从其他一些问题和答案来看,假设我所有的 MTU 都是 1,500,我感觉我可以发送 1,500 字节的数据而不会产生碎片。

那么...哪个是真的?

  1. 我的数据缓冲区的大小可以等于MTU

  2. 我的数据缓冲区必须是MTU - sizeof(various-headers/footers)

附:网络是我们 100% 控制的 LAN。数据包将使用 UDP 多播从一台主计算机传输到一组从属计算机。两者之间只有一个 1Gbps 交换机。仅此而已。

【问题讨论】:

  • 普遍接受的 UDP 有效负载的非分段限制为 534 字节。
  • 绝对小于 MTU。可能重复:stackoverflow.com/questions/4218553/…
  • @PaulSanders,是的。非常接近,尽管被选为答案的答案非常混乱。它没有回答如何编写 C/C++ 代码来获得正确的结果。我把我自己的答案和我的发现一起放在这里。
  • 简单的答案是假设路径 MTU 是 576 的最小值,如 RFC 1122/3 中所规定的那样,不确定是哪个,然后从那里开始。
  • @EJP,是的,但这并不是最佳选择。不过,我想我没有在我的问题中指定这一点......

标签: c++ udp mtu


【解决方案1】:

大小在 RFC-8085 中有非常明确的定义:UDP 使用指南

https://www.rfc-editor.org/rfc/rfc8085#section-3.2

有关于有效载荷大小计算的相关位。

要确定适当的 UDP 有效负载大小,应用程序必须从 PMTU 大小中减去 IP 标头(包括任何 IPv4 可选标头或 IPv6 扩展标头)的大小以及 UDP 标头的长度(8 个字节)。这个大小称为最大段大小 (MSS),可以从 TCP/IP 堆栈 [RFC1122] 中获得。

所以在 C/C++ 中,这变成:

#include <netinet/ip.h> // for iphdr
#include <netinet/udp.h> // for udphdr

int mss(udp.get_mtu_size());
mss -= sizeof(iphdr);
mss -= sizeof(udphdr);

警告: IP 标头的大小因选项而异。如果您使用会增加大小的选项,则您的 MSS 计算必须考虑到这一点。

此处不包括以太网页眉和页脚的大小,因为它们对 UDP 数据包是透明的。

【讨论】:

  • 不错的链接,在您的计算中可能允许有一点“倾斜”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多