那么这个 MTU 是不是我们使用 UDP 发送时的最大单次发送限制呢?不是,为了让传输层能够使用方便,即使传输层发送的数据大于 MTU 也没有关系,因为 IP 层会对大于 MTU 的数据进行分片,我们来看看 IP 层协议的头信息就知道了。
struct iphdr { __u8 version:4, ihl:4; __u8 tos; __be16 tot_len; __be16 id; __be16 frag_off; __u8 ttl; __u8 protocol; __sum16 check; __be32 saddr; __be32 daddr; /*The options start here. */ };
19518 和 19519 这两个数据包为同一个 IP 包的两个分片,是一次 ping 的请求,因为 2000 个用户字节肯定要分为两个 IP 分片,分两个以太网包发出去,上图为 19518 数据包的详细信息,其中 Total Length: 1500 表明本包数据总大小为 1500 包括 IP 头 (20) 和 IP 载荷(包括ICMP 头 8),即该包传送了 1500 - 20 个字节的 IP 载荷,那么下个分片的偏移应该从 1480 开始,Id 为 0xe1f8, MF 标志为 1,表示还有分片,下个包的详细信息为:
该分片 Id 与上个数据包相同,表明是同一个 IP 包,MF 标志为 0,表明是最后一包,偏移就是我们计算得来的 1480,总长度为 548,去除 IP 头,即 528, 第一个包中的 IP 载荷包含了 ICMP 头的 8 个字节,即,第一个包的用户数据为 1500 - 20 - 8 = 1472, 第二个包的用户数据为 548 - 20 = 528, 一共有 2000 用户数据,与理论一致。
协议栈分层的思想非常的清晰,每一层中只关心自己的头部信息与自己的载荷,而该层的载荷其实就是上一层的头部信息和上一层的载荷,每一层不会去关心上一层的头部信息与载荷的情况,这样就使得协议栈条理清晰并且易于扩展。
原文地址:http://blog.csdn.net/henzox/article/details/43230057