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

时间:2015-09-10 22:01:54

标签: c sockets networking kernel buffer

我无法发送大小超过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字节。我已成功发送大小约为60 KB的数据包,对于100 KB数据包,使用tcpdump进行捕获显示数据包甚至没有被发送并且可能被内核丢弃(我在tcpdump中看不到它们)迹线)。

我还需要做些什么来传输大型数据包(最好是大小为100 MB)?

2 个答案:

答案 0 :(得分:7)

UDP数据报必须适合单个IP数据报。 IP报头中的Total Length字段为16位,因此最大长度(包括IP和UDP报头)为65535字节。 UDP header也有一个16位Length字段。 UDP长度字段包括UDP报头,而不是IP报头,但由于整个UDP数据报必须适合IP数据包的有效负载,因此它受IP长度的限制。

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

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

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

答案 1 :(得分:2)

在最低级别,这是不可能的。

根据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字段会计算标题的大小 ,因此它的最小值为8,最大有效负载大小为{{ 1}}。

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

希望这能帮到你!