如何发送大小大于 64 KB 的 UDP 数据包

How to send UDP packets of size greater than 64 KB

我无法发送大小超过 64 KB 的 IP multicast datagrams(我需要发送,用于我的实验)。我正在通过 10 Gigabit ethernet 链接直接连接的计算机之间传输数据包(中间没有任何跃点,由 traceroute 确认)。

所有计算机都安装了 Ubuntu 12.04。我通过在 /etc/sysctl.conf 中添加以下行来更改读写缓冲区的限制:

net.core.rmem_max=12582912
net.core.wmem_max=12582912
net.core.rmem_default=12582912
net.core.wmem_default=12582912

并使用 sysctl -a 验证更改(在 运行 sysctl -p 之后)。我需要重新启动才能看到更改吗? (我共享机器,所以重启并不总是可能的)。

用于发送和接收的接口MTU在所有计算机中都是9000 Bytes。我已经成功地发送了大小约为 60 KB 的数据包,对于 100 KB 的数据包,使用 tcpdump 捕获显示数据包甚至没有发送并且可能被内核丢弃(我没有在 tcpdump 中看到它们跟踪)。

我还需要做什么才能传输大数据包(最好是 100 MB 左右的大小)?

UDP 数据报必须适合单个 IP 数据报。 Total Length field in the IP header is 16 bits, so the maximum length (including the IP and UDP headers) is 65535 bytes. The UDP header 也有一个 16 位的 Length 字段。 UDP 长度字段包括 UDP header,而不是 IP header,但由于整个 UDP 数据报必须适合 IP 数据包的有效负载,因此它受到 IP 长度的限制。

因此无法发送大于 64KB 的 UDP 数据报。由于 IP 和 UDP header 的最小大小分别为 20 字节和 8 字节,因此实际最大负载量最多为 65507 字节。

如果您需要发送较大的消息,则需要将其分解为多个数据报。或者您也许应该考虑使用不同的传输协议,例如 TCP(不幸的是,如果您正在进行多播,这是不可能的)。

IPv6 支持大于 64K 的 Jumbograms。但是你不能在 IPv4 中做到这一点。

最底层是不可能的。

根据 RFC 768 - User Datagram Protocol,UDP 数据包的结构类似于...

              0      7 8     15 16    23 24    31
             +--------+--------+--------+--------+
             |     Source      |   Destination   |
             |      Port       |      Port       |
             +--------+--------+--------+--------+
             |                 |                 |
             |     Length      |    Checksum     |
             +--------+--------+--------+--------+
             |
             |          data octets ...
             +---------------- ...

                  User Datagram Header Format

这意味着保存数据包大小的Length字段是16位长。然后,我们得到 2^16-1 等于 65535,因此该数字是 Length 字段可能包含的最大值。当然,65535 与 64KiB 相差仅一字节。也许有 UDP 的扩展可以解决这个问题,但我不知道有什么。无论如何,碰巧 Length 字段也计算 header 的大小 ,所以它的最小值是 8,而最大值有效负载大小为 65535-8=65527.

无论如何,我不确定您是否使用了正确的协议,或者至少是否使用了正确的数据操作模型。 UDP 肯定是您(唯一?)用于多播目的的最佳选择,但 UDP 旨在传输 small 数据包而不提供传输控制协议创建的连接错觉以克服 Internet 协议的不可靠的 connection-less 信息传递方式。 UDP 只是一个小的改进,在此基础上添加了端口。

希望对您有所帮助!