【发布时间】:2011-06-02 13:42:12
【问题描述】:
我正在开发一个 tftp 客户端和服务器,我想动态选择 udp 负载大小以提高传输性能。
我已经用两台 linux 机器测试了它(一台有千兆以太网卡,另一台有快速以太网卡)。我把千兆网卡的MTU改成2048字节,另一个留1500。
我使用setsockopt(sockfd, IPPROTO_IP, IP_MTU_DISCOVER, &optval, sizeof(optval)) 将MTU_DISCOVER 标志设置为IP_PMTUDISC_DO。
根据我的阅读,此选项应将 DF 位设置为 1,因此应该可以找到网络的最小 MTU(具有最低 MTU 的主机的 MTU)。然而,当我发送一个大小大于我发送数据包的机器的 MTU 的数据包时,这件事只会给我一个错误。
另外另一台机器(在这种情况下是服务器)没有接收到超大数据包(服务器的 MTU 为 1500)。所有的UDP包都被丢弃,唯一的办法是发送1472字节的包。
为什么主机要这样做?根据我的阅读,如果我发送的数据包大于 MTU,ip 层应该对其进行分段。
【问题讨论】:
-
如果 MTU 发现开启,IP 层还会对数据包进行分段吗?
-
DF 位不能防止碎片吗?
-
离场。那么发送主机应该自己发现MTU吗?还是底层图书馆为他做的?
-
感谢大家的回复。我应该添加一些关于我的实验的内容。我尝试过使用 tracepath (此实用程序执行路径 MTU 发现)。我已将 MTU 设置为 4096,当我启动 tracepath 时,我自己的主机说消息太长,因此 tracepath 减小了消息大小。然而,就消息通过本地主机而言,没有其他主机会发出错误信号。 Tracepath 将继续发送 4096 字节长的消息,远程主机将愉快地丢弃它们,而不发送 ICMP 回复。
-
您需要记住,ICMP 交付是尽力而为,不可靠,而且许多防火墙都配置为只允许 ICMP 回显数据包,而不允许其他类型。
标签: linux networking udp