以太网(Ethernet)数据帧的长度必须在 64Bytes-1518Bytes 字节之间,这是由于以太网传输电气方面限制的,EthernetII 协议报头结构如下:
| 目的地址(DMAC) | 源地址(SMAC) | 类型(TYPE) | 数据(DATA) | 校验(CRC) |
6Bytes 6Bytes 4Bytes 46-1500Bytes 2Bytes
由于以太网最大的数据帧是 1518Bytes,刨去以太网帧的帧头(目标MAC地址,源MAC地址和类型)14Bytes 以及帧尾 CRC 校验部分4Bytes 那么剩下承载上层协议的地方也就是 Data 域最大就只能有1500Bytes 这个值我们就把它称之为 MTU。
- UDP 包的大小就应该是 1500 - IP头(20) - UDP头(8) = 1472(BYTES)
- TCP 包的大小就应该是 1500 - IP头(20) - TCP头(20) = 1460 (BYTES)
注:PPPoE导致MTU变小了,以太网的 MTU 是 1500,再减去PPP的包头包尾的开销(8Bytes),MTU 就变成1492。
MTU 对我们的 UDP 编程很重要,那如何查看路由的MTU值呢?
# windows OS: ping -f -l
$ ping -f -l 1472 www.bing.com
#如果提示:需要拆分数据包但是设置 DF。
#则表明 MTU 小于1500,不断改小data_length值,可以最终测算出gateway的MTU值。
#linux OS: ping -c -M do -s
$ ping -c 1 -M do -s 1472 www.bing.com
#如果提示 Frag needed and DF set……
#则表明 MTU 小于 1500,可以再测以推算 gateway 的 MTU。
如果数据超过 MTU 范围,既 IP 数据报大于 1500 字节,发送方 IP 层就需要将数据包分成若干片,而接收方 IP 层就需要进行数据报的重组。更严重的是,如果使用UDP协议,当IP层组包发生错误,那么包就会被丢弃,接收方无法重组数据报,将导致丢弃整个IP数据报。UDP 不保证可靠传输。但是 TCP 发生组包错误时,该包会被重传,保证可靠传输。
因此,在普通的局域网环境下,建议将UDP的数据控制在1472字节以下为好。鉴于 Internet 上的标准 MTU 值为 576 字节,所以建议在进行 Internet 的 UDP 编程时,最好将 UDP 的数据长度控件在 548 字节(576-20-8)以内。
网友评论