linux tcpip
MTU,即Maximum Transmission Unit(最大传输单元),此值设定TCP/IP协议传输数据报时的最大传输单元。
网络 头 最小MTU 最大MTU
PPP 6 128 65535
Ethernet 38 46 1500
TCP/IP 40 576 65535
一个包裹在达到MTU设定的尺寸之前不会被送出。如果MTU值很大,很明显延迟也更长。但是,如果MTU值太小,头会占据大量带宽,从而减低带宽的有效性.
如何检测网关的MTU?
在本机打开dos窗口,执行:
ping -f -l 1472 192.168.0.1
其中192.168.0.1是网关IP地址,1472是数据包的长度。请注意,上面的参数是“-l”(小写的L),而不是“-1”。
如果能ping通,表示数据包不需要拆包,可以通过网关发送出去。
如果出现: Packet needs to be fragmented but DF set.
表示数据包需要拆开来发送。此时,减少数据包长度,再执行上面的ping命令。从1400到1472之间多试几次,就能找到合适的数据包长度了。把数据包长度加上数据包头28字节,就得到MTU的值。
如果检测到网关的MTU值是1500,不需要修改。
如果网关有防火墙ping不通,可以试试直接把MTU设为1400。防止MTU设置不合理导致的链路不通问题
需要关注在IP隧道技术,如LVS的LD到RS,IPSEC等使用IP隧道导致的MTU增大(注:IP隧道技术是使用IP传送IP包的技术,会在原来的IP包加上新的IP头等信息,导致IP包大小变大,可能超过了MTU的值),超过对应client或者server的最大MTU导致链接不通的情况,这个时候,一般会反向通过icmp包周知告诉发送端,比如:这个ICMP包告诉发送源端,下一跳的MTU是1450,你发送的包太大需要分片。但是你的包IP头里面设置了不可分片,所以我只能把包丢掉,通知你一下,重发小一点的包过来。
IP分片
ping 192.168.0.1 -l 1473
按刚才的说法,1473+20(ip头)+8(icmp头)=1501,则好大于1500,它会被分片,但是,我们关心的是:
这个数据包会被怎么样分法?
可以猜想,第一个包是
以太头+IP头+ICMP头+1427的数据;
那第二个分片包呢?
它可以是:
以太头+IP头+ICMP头+1个字节的数据
或者是:
以太头+IP头+1个字节的数据
也就是省去ICMP头的封装,当然,IP头是不可以省的,否则怎么传输了……
事实上,TCP/IP协议采用的是后一种封装方式,这样,一次可以节约8个字节的空间。IP包头中,用了三个标志来描述一个分片包:
1、分片标志:如果一个包被分片了,被置于1,最后一个分片除外;——这样,对于接收端来讲,可以根据这个标志位做为重组的重
要依据之一;
2、分片偏移标志:光有一个标志位说明“自己是不是分片包”是不够的,偏移标志位说明了自己这个分片拉于原始数据报的什么位置,
很明显,这两个标志一结合,就很容易重组分片包了。
3、不允许分片标志:如果数据包强行设置了这个标志,那么在应该分片的时候,…… err,刚才已经说过了
IP分片和TCP分片 MTU和MSS
使用UDP很容易导致IP分片,TCP试图避免IP分片。那么TCP是如何试图避免IP分片的呢?其实说白了,采用TCP协议进行数据传输是不会造成IP分片的,因为一旦TCP数据过大,超过了MSS,则在传输层会对TCP包进行分段(如何分,见下文!),自然到了IP层的数据报肯定不会超过MTU,当然也就不用分片了。而对于UDP数据报,如果UDP组成的IP数据报长度超过了1500,那么IP数据报显然就要进行分片,因为UDP不能像TCP一样自己进行分段。总结:UDP不会分段,就由我IP来分。TCP会分段,当然也就不用我IP来分了!
2,MSS(Maxitum Segment Size)最大分段大小的缩写,是TCP协议里面的一个概念
(1)MSS就是TCP数据包每次能够传输的最大数据分段。为了达到最佳的传输效能TCP协议在建立连接的时候通常要协商双方的MSS值,这个值TCP协议在实现的时候往往用MTU值代替(需要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes)所以往往MSS为1460。通讯双方会根据双方提供的MSS值得最小值确定为这次连接的最大MSS值。
(2)相信看到这里,还有最后一个问题:TCP是如何实现分段的呢?其实TCP无所谓分段,因为每个TCP数据报在组成前其大小就已经被MSS限制了,所以TCP数据报的长度是不可能大于MSS的,当然由它形成的IP包的长度也就不会大于MTU,自然也就不用IP分片了。