全部博文(1015)
分类:
2010-07-29 18:02:45
小议TCP的MSS(最大分段)以及MTU
[前言]
漫漫51长假,没有好的去处,只能每日上网消遣,某日逛到NBO灌水,见一帖曰:无法通过上MSN(出口为线路,通过PPPoE)吾心想,ADSL---PPPoE,那肯定就是MTU之问题。回帖告之:改PC之MTU。
过数日,又逛到NBO,又见这帖,后有人回曰:ip tcp adjust-mss 1452后帖主又跟:问题解决。
吾纳闷之,后百思而得其解,So决 定将自己所得写出来,分享给大家。
[背景知识]
MTU: Maxitum Transmission Unit 最大传输单元
MSS: Maxitum Segment Size 最大分段大小(偶是直译,翻译的不好,不要打
俺PP)
PPPoE: PPP Over Ethernet(在以太网上承载PPP协议)
[分析过程]
先说说这MTU最大传输单元,这个最大传输单元实际上和链路层协议有着密切的关系,让我们先仔细回忆一下EthernetII帧的结构DMAC+SMAC+Type+Data+CRC
由于以太网传输电气方面的限制,每个以太网帧都有最小的大小64bytes最大不能超过1518bytes,对于小于或者大于这个限制的以太网帧我们都可以视之为错误的数据帧,一般的以太网转发设备会丢弃这些数据帧。
(注:小于64Bytes的数据帧一般是由于以太网冲突产生的“碎片”或者线路干扰或者坏的以太网接口产生的,对于大于1518Bytes的数据帧我们一般把它叫做Giant帧,这种一般是由于线路干扰或者坏的以太网口产生)
由于以太网EthernetII最大的数据帧是1518Bytes这样,刨去以太网帧的帧头(DMAC目的MAC地址48bit=6Bytes+SMAC源MAC地址48bit=6Bytes+Type域2bytes)14Bytes和帧尾CRC校验部分4Bytes(这个部门有时候大家也把它叫做FCS),那么剩下承载上层协议的地方也就是Data域最大就只能有Bytes这个值我们就把它称之为MTU。这个就是层协议非常关心的地方,因为网络层协议比如IP协议会根据这个值来决定是否把上层传下来的数据进行分片。就好比一个盒子没法装下一大块面包,我们需要把面包切成片,装在多个盒子里面一样的道理。
当两台远程PC互联的时候,它们的数据需要穿过很多的路由器和各种各样的网络媒介才能到达对端,网络中不同媒介的MTU各不相同,就好比一长段的水管,由不同粗细的水管组成(MTU不同 )通过这段水管最大水量就要由中间最细的水管决定。
对于网络层的上层协议而言(我们以TCP/IP协议族为例)它们对水管粗细不在意它们认为这个是网络层的事情。网络层IP协议会检查每个从上层协议下来的数据包的大小,并根据本机MTU的大小决定是否作“分片”处理。分片最大的坏处就是
降低了传输性能,本来一次可以搞定的事情,分成多次搞定,所以在网络层更高一层(就是传输层)的实现中往往会对此加以注意!有些高层因为某些原因就会要求我这个面包不能切片,我要完整地面包,所以会在IP数据包包头里面加上一
个标签:DF(Donot Fragment)。这样当这个IP数据包在一大段网络(水管里面)传输的时候,如果遇到MTU小于IP数据包的情况,转发设备就会根据要求丢弃这个数据包。然后返回一个错误信息给发送者。这样往往会造成某些通讯上的问题,不过幸运的是大部分网络链路都是MTU1500或者大于1500。
对于UDP协议而言,这个协议本身是无连接的协议,对数据包的到达顺序以及是否正确到达不甚关心,所以一般UDP应用对分片没有特殊要求。
对于TCP协议而言就不一样了,这个协议是面向连接的协议,对于TCP协议而言它非常在意数据包的到达顺序以及是否传输中有错误发生。所以有些TCP应用对分片有要求---不能分片(DF)。
花开两朵,各表一枝,说完MTU的故事我们该讲讲今天的第二个猪脚---PPPoE所谓PPPoE就是在以太网上面跑PPP协议,有人奇怪了,PPP协议和Ethernet不都是链路层协议吗?怎么一个链路层跑到另外一个链路层上面去了,难道升级成网络层协议了不成。其实这是个误区:就是某层协议只能承载更上一层协议。
为什么会产生这种奇怪的需求呢?这是因为随着宽带接入(这种宽带接入一般为Cable Modem或者xDSL或者以太网的接入)由于以太网缺乏认证计费机制而传统运营商是通过PPP协议来对拨号等接入服务进行认证计费的,所以就出了这么一个怪胎:PPPoE。(有关PPPoE的详细介绍参见V大以及本站其他成员的一些介绍文章,我就不啰里啰唆的了)
PPPoE带来了好处,也带来了一些坏处,比如:二次封装耗费资源,降低了传输效能等等,这些坏处俺也不多说了,最大的坏处就是PPPoE导致MTU变小了以太网的MTU是1500,再减去PPP的包头包尾的开销(8Bytes),就变成1492。
如果两台主机之间的某段网络使用了PPPoE那么就会导致某些不能分片的应用无法通讯。
这个时候就需要我们调整一下主机的MTU,通过降低主机的MTU,这样我们就能够顺利地进行通讯了。
当然对于TCP应用而言还有另外的解决方案。
马上请出今天第三位猪脚:MSS。
MSS最大传输大小的缩写,是TCP协议里面的一个概念。
MSS就是TCP数据包每次能够传输的最大数据分段。为了达到最佳的传输效能TCP协议在建立连接的时候通常要协商双方的MSS值,这个值TCP协议在实现的时候往往用MTU值代替(需要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes)所以往往MSS为1460。通讯双方会根据双方提供的MSS值得最小值确定为这次连接的最大MSS值。
介绍完这三位猪脚s
我们回过头来看前言里面的那个问题,我们试想一下,如果我们在中间路由器上把每次TCP连接的最大MSS进行调整这样使得通过PPPoE链路的最大MSS值加上数据包头包尾不会超过PPPoE的MTU大小1492这样就不会造成无法通讯的问题.所以上面的问题可以通过ip tcp adjust-mss 1452来解决。
当然问题也可以通过修改PC机的MTU来解决。
MSS: Maxitum Segment Size 最大分段大小
MSS最大传输大小的缩写,是TCP协议里面的一个概念。
MSS就是TCP数据包每次能够传输的最大数据分段。为了达到最佳的传输效能
TCP协议在建立连接的时候通常要协商双方的MSS值,这个值TCP协议在实现的
时候往往用MTU值代替(需要减去IP数据包包头的大小20Bytes和TCP数据段的
包头20Bytes)所以往往MSS为1460。通讯双方会根据双方提供的MSS值得最小
值确定为这次连接的最大MSS值。
从windows开始>运行"regedit"开启注册表编辑,选HKEY_Local_Machine>SYSTEM>CurrentControlSet>Services>Tcpip>Parameters>interface,有点像下面的图示:
interface 底下可能有很多的介面,你一个一个的去看,会有一个界面点击后右边数据中有与你的IP相同的,那个就是你要挑选的界面。然后在该界面上选择编辑>新增>DWORD值或双字节值之后,建立一个名为MTU的键值,然后选右键修改,选择十进位,填入值为XXXX(参见:如何获得MTU值)。保存退出后,重新启动计算机即可。
如何获得MTU值
进入MS DOS>ping -f -l 1433 192.168.X.X(局域网内能ping到的IP) >如下:
c:\windows>ping -f -l 1433 192.168.X.X
注:上面的式子中,-l 是 L 的小写(不是 1 )
Pinging 192.168.X.X with 1500 bytes of data:
Packet needs to be fragmented but DF set
Packet needs to be fragmented but DF set
……
……
如果显示为以上信息,表明值过大。你需要更小的 MTU 值才行!
c:\windows>ping -f -l 1432 192.168.X.X
Pinging 192.168.X.X with 1500 bytes of data:
Reply from 192.168.X.X: bytes=1432 time=10ms TTL=128
Reply from 192.168.X.X: bytes=1432 time=10ms TTL=128
……
……
出现回应,表明值可行。
不过,强烈建议找出最大可行的MTU值,这样才能获得最佳的网络速度
不过上面找出的值还不是最终在注册表中设定的MTU 值,还需要加上28,所以,最终设定的 MTU 值是 1432+28=1460
注册表设置完成,重启计算机,再试试看会不会有效果
总结:
MTU=40 Bytes+MSS
以太网MTU最大为1500 Bytes,MSS最大为1460 Bytes;
ping -f -l 1434 202.100.98.31 把数据包长度加上数据包头28字节,就得到MTU的值1434+28=1462,也就是我的最佳mtu是1462
PPPoE链路中,采用了二次封装耗费资源,降低了传输效能等等,最大的坏处就是PPPoE导致MTU变小了以太网的MTU是1500,再减去PPP的包头包尾的开销(8Bytes),就变成1492。如果两台主机之间的某段网络使用了PPPoE那么就会导致某些不能分片的应用无法通讯。这个时候就需要我们调整一下主机的MTU,通过降低主机的MTU,这样我们就能够顺利地进行通讯了。MTU最大为1492 Bytes,MSS这时为1452 Bytes
MTU设置问题造成adsl故障,这个现象在adsl里很普遍,如果本机的MTU比猫的MTU大,大的数据包就会被拆开来传送,甚至丢弃,这样就会造成能ping通外部地址和外部域名但打不开网页,或打不开部分网站。
检测mtu的方法很简单,用ping即可,在本机打开dos窗口,执行:
ping -f -l 1472 202.100.98. 31其中202.100.98. 31是外部本地的IP地址,1472是数据包的长度。请注意,上面的参数是“-l”(小写的L),而不是“-1”。 如果能ping通,表示数据包不需要拆包,可以通过网关发送出去。 如果出现: Packet needs to be fragmented but DF set. 表示数据包需要拆开来发送。此时,减少数据包长度,再执行上面的ping命令。从1400到1472之间多试几次,就能找到合适的数据包长度了。把数据包长度加上数据包头28字节,就得到MTU的值。
C:\Documents and Settings\Administrator>ping -f -l 1434 202.100.98.31
Pinging 202.100.98.31 with 1434 bytes of data:
Reply from 202.100.98.31: bytes=1434 time=45ms TTL=123
Ping statistics for 202.100.98.31:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 45ms, Maximum = 45ms, Average = 45ms
Control-C
^C
C:\Documents and Settings\Administrator>ping -f -l 1435 202.100.98.31
Pinging 202.100.98.31 with 1435 bytes of data:
Packet needs to be fragmented but DF set.
Ping statistics for 202.100.98.31:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),
从上面可以看出数据包大小为1434刚好可以ping通,1434+28=1462,也就是我的最佳mtu是1462,这也就是很多adsl优化的秘密,
至于mtu mss之类的原理问题百度很多,搜索一下吧,另外发现宁夏dns202.100.96.68只能支持很小的数据包,不知道dns服务器怎么设置的,或者前面加个防火墙之类的,肯定有问题了,所以我现在很少用宁夏的dns服务器,基本上使用中国总dns202.97.7.17
C:\Documents and Settings\Administrator>ping -f -l 800 202.100.96.68
Pinging 202.100.96.68 with 800 bytes of data:
Reply from 202.100.96.68: bytes=800 time=34ms TTL=248
Reply from 202.100.96.68: bytes=800 time=35ms TTL=248
Reply from 202.100.96.68: bytes=800 time=36ms TTL=248
Ping statistics for 202.100.96.68:
Packets: Sent = 3, Received = 3, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 34ms, Maximum = 36ms, Average = 35ms
Control-C
^C
C:\Documents and Settings\Administrator>ping -f -l 801 202.100.96.68
Pinging 202.100.96.68 with 801 bytes of data:
Request timed out.
Request timed out.
Request timed out.
Request timed out.
北京的dns,
C:\Documents and Settings\Administrator>ping -f -l 1434 202.97.7.17
Pinging 202.97.7.17 with 1434 bytes of data:
Request timed out.
Reply from 202.97.7.17: bytes=1434 time=65ms TTL=248
Reply from 202.97.7.17: bytes=1434 time=66ms TTL=248
Ping statistics for 202.97.7.17:
Packets: Sent = 3, Received = 2, Lost = 1 (33% loss),
Approximate round trip times in milli-seconds:
Minimum = 65ms, Maximum = 66ms, Average = 65ms
Control-C
^C
C:\Documents and Settings\Administrator>ping -f -l 1435 202.97.7.17
Pinging 202.97.7.17 with 1435 bytes of data:
Packet needs to be fragmented but DF set.
Packet needs to be fragmented but DF set.
各种应用下的最佳MTU值
设置 MTU 大小是一个反复试验的过程: 由最大值 1500开始下降,直至问题解决。使用下列值之一或许能解决一些由MTU值引起的问题:
• 1500: 以太网信息包最大值,也是默认值。是没有PPPoE和VPN 的网络连接的典型设置。是 UCOM 路由器、网络适配器和交换机的默认设置
• 1492: PPPoE 的最佳值
• 1472: 使用 ping的最大值 (大于此值的信息包会先被分解)
• 1468: DHCP 的最佳值
• 1430: VPN 和 PPTP 的最佳值
• 576: 拨号连接到 ISP的标准值
如何得出最佳的MTU值
1、进入 MS-DOS 模式;
2、打入 C:\WINDOWS>ping -f -l 1500 192.168.1.1。
其中192.168.1.1是网关IP地址,1500是数据包的长度。请注意,上面的参数是“-l”(小写的L),而不是“-1”。
如果出现下面信息:Packet needs to be fragmented but DF set