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

我无法发送大小超过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 -avalidation了更改(运行sysctl -p之后)。 我是否需要重新启动才能看到更改? (我正在共享机器,所以不总是可以重启)。

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

为了能够传输大数据包(最好是100 MB的大小),我还需要做些什么?

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

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

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

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

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

根据RFC 768 – 用户数据报协议 ,UDP数据包的结构看起来像……

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

这意味着保持数据包大小的Length字段Length为16位。 然后,我们得到2^16-1等于65535,因此该数字是Length字段可能包含的最大值。 当然,65535距离正好是64KiB只有一个字节。 也许有UDP的扩展可以解决这个问题,但我不知道。 无论如何, Length字段也会计算标头的大小,因此它的最小值为8 ,最大有效负载大小为65535-8=65527

无论如何,我不确定你是使用正确的协议,还是至少使用正确的数据处理模型。 UDP肯定是您(唯一?)用于多播目的的最佳选择,但UDP旨在传输数据包,而不提供传输控制协议创建的连接,以克服Internet协议不可靠,无连接的传输信息的方式。 UDP只是一个小改进,它增加了端口。

希望这对你有所帮助!