2009-09-08 11:24:00 +0000 2009-09-08 11:24:00 +0000
21
21

如何判断Windows XP中使用的MTU是什么?

我正在遭受一个非常奇怪的问题,当我试图访问网页时,我随机得到 “与服务器的连接被重置 "的错误(根据Windows网络诊断工具,HTTP错误12031)–无论我试图访问的网页是否在外部互联网上,或者即使它来自运行在localhost上的本地Apache实例,都会发生这种情况。它影响了我们本地网络上的所有计算机(以太网,而不是无线),所有这些计算机都在运行Windows XP。

有人建议我,这可能与网络流量使用的MTU有关。如果我做Ping测试找出最大的数据包,可以通过无碎片,我可以ping本地主机与1492字节的包(+28字节的头?),我可以ping我们的路由器与1462字节的包(这是1490字节,当你包括28字节的头)。如果我试着ping一些外部的东西,比如Google,我不能得到任何大于1430的东西(包括头在内是1458)。

我试着按照各种指示更新Windows XP注册表中的MTU设置,更新HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{AdapterID}\MTU。我已经尝试了无尽的替代值:最明显的正确值似乎是1490,但我也试过1462,1458,1430,等等等等。当我重启电脑使更改生效时,它似乎能工作几分钟(很难说清楚,因为它总是随机的,而不是一致的),但它从来没有持续很长时间。

起初,当我尝试用1430作为数值时,在正常工作几分钟后,Ping测试的结果会减少28个字节–突然我发现我只能通过谷歌获得1402字节的包。如果我把MTU注册表设置更新为1402,当我重启并等待几分钟后,它就会变成1374,然后是1346,等等等等。网络上的其他电脑仍然不受影响(仍然是1430),从注册表中删除MTU设置就可以恢复正常(而且还是坏的)。

我觉得诊断这一切最难的是,很难判断我是否玩了正确的注册表设置。所以,最简单的,我的问题是。**

另外,如果有人知道为什么MTU一直在下降28,那也是很有用的(例如,是否有一个Windows的日志文件,它会在值变化的地方记录一些东西?

最后,如果有人能告诉我如何明确地告诉我应该尝试使用什么MTU设置,那将是非常好的。

答案 (5)

58
58
58
2011-08-02 02:59:21 +0000

对于Windows 7、Windows Vista和Windows XP,各种接口的MTU可以从Windows本身使用netsh获得。

Windows 7、Windows Vista

要在Windows 7或Windows Vista上显示当前MTU,从命令提示符。

C:\Users\Ian>netsh interface ipv6 show subinterfaces

       MTU MediaSenseState Bytes In Bytes Out Interface
---------- --------------- --------- --------- -------------
      1280 1 24321220 6455865 Local Area Connection
4294967295 1 0 1060111 Loopback Pseudo-Interface 1
      1280 5 0 0 isatap.newland.com
      1280 5 0 0 6TO4 Adapter

对于IPv4接口:

C:\Users\Ian>netsh interface ipv4 show subinterfaces

       MTU MediaSenseState Bytes In Bytes Out Interface
---------- --------------- --------- --------- -------------
      1500 1 146289608 29200474 Local Area Connection
4294967295 1 0 54933 Loopback Pseudo-Interface 1

注意:在这个例子中,我的局域网连接IPv6接口有这么低的MTU(1280),因为我使用隧道服务来获得IPv6连接.

你也可以改变你的MTU (Windows 7, Windows Vista)。从一个高阶_命令提示符。

>netsh interface ipv4 set subinterface "Local Area Connection" mtu=1492 store=persistent
Ok.

Tested with Windows 7 Service Pack 1

Windows XP

Windows XP的netsh语法略有不同:

C:\Users\Ian>netsh interface ip show interface

Index: 1
User-friendly Name: Loopback
Type: Loopback
MTU: 32767
Physical Address:                       

Index: 2
User-friendly Name: Local Area Connection
Type: Etherenet
MTU: 1500
Physical Address: 00-03-FF-D9-28-B7

注意。 ** Windows XP要求在你看到接口的详细信息(包括MTU)之前,必须先启动路由和远程访问**服务:

C:\Users\Ian>net start remoteaccesss

Windows XP不提供在netsh内更改MTU设置的方法。为此,您可以 TCP ](http://support.microsoft.com/kb/283165) ( 注: 仅限 Windows 2000/XP)

用 Windows XP Service Pack 3测试

另请参见


关于MTU是什么的简短讨论,28个字节来自哪里。

你的网卡(以太网)的最大数据包大小为1,500 bytes

+---------+
| 1500 |
| byte |
| payload |
| |
| |
| |
+---------+

TCP/IP的IP部分需要一个20字节的头(12字节的标志,4字节的源IP地址,4字节的目的IP地址)。这使得数据包中的可用空间减少。

+------------------------+
| 12 bytes control flags | \
| 4 byte from address | |- IP header: 20 bytes
| 4 byte to address | /
|------------------------|
| 1480 byte payload |
| |
| |
| |
+------------------------+

现在一个ICMP(ping)数据包有一个8字节的头(1个字节type,1个字节code,2个字节checksum,4个字节附加数据):

+------------------------+
| 12 bytes control flags | \
| 4 byte from address | |
| 4 byte to address | |- IP and ICMP header: 28 bytes
|------------------------| |
| 8 byte ICMP header | /
|------------------------|
| 1472 byte payload |
| |
| |
| |
+------------------------+

这就是 “缺失 "的28个字节–这是发送ping数据包所需的头的大小。

当你发送ping数据包时,你可以指定你想包含多少额外的有效载荷数据。在本例中,如果你包含了所有1472个字节:

>ping -l 1472 obsidian

那么产生的ethernet数据包就会满满当当。1500个字节数据包中的每一个字节都会被填满。

+------------------------+
| 12 bytes control flags | \
| 4 byte from address | |
| 4 byte to address | |- IP and ICMP header: 28 bytes
|------------------------| |
| 8 byte ICMP header | /
|------------------------|
|........................|
|........................|
|. 1472 bytes of junk....|
|........................|
|........................|
|........................|
|........................|
+------------------------+

如果你想多发一个字节

>ping -l 1473 obsidian

网络将不得不把1501字节的数据包分割成多个数据包。

Packet 1 of 2
+------------------------+
| 20 bytes control flags | \
| 4 byte from address | |
| 4 byte to address | |- IP and ICMP header: 28 bytes
|------------------------| |
| 8 byte ICMP header | /
|------------------------|
|........................|
|........................|
|..1472 bytes of payload.|
|........................|
|........................|
|........................|
|........................|
+------------------------+

Packet 2 of 2
+------------------------+
| 20 bytes control flags | \
| 4 byte from address | |
| 4 byte to address | |- IP and ICMP header: 28 bytes
|------------------------| |
| 8 byte ICMP header | /
|------------------------|
|. |
| 1 byte of payload |
| |
| |
| |
| |
| |
+------------------------+

这种碎片化会在幕后发生,最好是在你不知情的情况下。

但你可以刻薄一点,告诉网络不允许数据包被碎片化:

>ping -l 1473 -f obsidian

-f标志的意思是_不要碎片化。现在当你试图发送一个不适合网络的数据包时,你会得到错误的信息:

>ping -l 1473 -f obsidian  

Packet needs to be fragmented but DF set.

-f标志的意思是do not fragment

0x1&

数据包需要被分割,但是Do not Fragment标志被设置了。

如果沿线任何地方的数据包需要被碎片化,网络实际上会发送一个ICMP数据包告诉你发生了碎片化。你的机器收到了这个ICMP包,被告知最大的大小是多少,并且应该停止发送太大的数据包。不幸的是,大多数防火墙会阻止这些 "路径MTU发现 "的ICMP数据包,所以你的机器永远不会意识到数据包被碎片化了(或者更糟糕的是:因为它们不能被碎片化而被丢弃)。

这就是导致web-server无法工作的原因。你可以得到最初的小的(<1280字节)响应,但是更大的数据包却无法通过。而且web服务器的防火墙配置错误,屏蔽了ICMP数据包。所以web服务器并不知道你从来没有收到过数据包。

在IPv6中不允许数据包的碎片化,大家都是_必须(正确)允许ICMP mtu发现数据包。

8
8
8
2011-11-07 19:52:04 +0000

@ian 我不太确定netsh是否真的显示了当前使用的MTU。在我的 Windows XP Pro SP3 机器上,我执行 netsh interface ip show interface,它报告相关接口的 MTU 值为 1500。然后我添加了以下注册表键。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\EnablePMTUDiscovery
    value: 0

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{ID}\MTU 
    value: various (e.g. 1200)

微软说 EnablePMTUDiscovery设置为0将MTU设置为576。

设置MTU注册表项可以手动设置MTU。我尝试了几个MTU条目的值(每次重启)。

在这两种情况下–先添加第一个条目,再添加第二个条目–netsh仍然报告MTU为1500。用ping测试证实(或至少表明),注册表中配置的MTU值确实被使用了。

另外,当我第一次在我的机器上尝试时,路由和远程访问服务是被禁用的,所以我无法使用您的说明来启动它。我通过进入控制面板/>管理工具/>计算机管理/>服务和应用程序/>服务来启用它。我把 “启动类型 "从禁用改为手动。然后我也从该对话框中启动了该服务。

我也不确定KB283165是否一定是改变MTU的正确指令。这些说明不是只有在运行Windows PPPoE客户端时才有意义吗?如果通过路由器连接到互联网,路由器是PPPoE客户端(就像我的情况一样),这些指令就不相关了吧?

我遵循的说明,使我对注册表进行了上述修改,是在 KB900926: 对于MTU大小小于576的WAN链路,推荐的TCP/IP设置(方法2和3)。


编辑:@ian

看来你是对的。配置为1,200,但netsh报告1500

>ping -l 1173 -f obsidian

Packet needs to be fragmented but DF set.

所以我想最初问题的答案是,在Windows XP上,你必须使用Do not fragment标志进行试错,找到你能发送的最大数据包。然后你就有了你的MTU。

2
2
2
2009-09-08 11:47:58 +0000

你可以用ping试错的方法找到MTU:

ping <address> -f -l nnnn

-f 。指定在发送 Echo Request 消息时,IP 头中的 Don’t Fragment 标志设置为 1,Echo Request 消息不能被路径中的路由器碎片化。该参数对于排除路径最大传输单元(PMTU)问题很有用。

-l Size : 指定发送的 Echo Request 消息中数据字段的长度,以字节为单位。默认值为32。最大尺寸是 65,527。

当长度过大时,你会得到 “数据包需要被分割,但DF设置 "的消息。

1
1
1
2009-09-08 11:28:05 +0000

微软KB314496。不同网络拓扑的默认MTU大小
在正常的网络设置中,你不应该尝试玩弄MTU配置。

这里有一个【VB代码参考】(http://www.codeproject.com/KB/IP/NetworkConfigTool.aspx)。
还有一个工具叫 DrTCP

  • *

在注册表中,

  • 转到HKLM\Software\Microsoft\Windows NT\CurrentVersion\NetworkCards
  • 打开你感兴趣的适配器
  • 复制ServiceName字符串
  • HKLM\System中搜索该字符串;你将匹配一个NetCfgInstanceId
  • 上面一点就是MaxFrameSize键(我的显示为1514)

还有一种方法可以用netsh命令来改变它。

另外,检查你的路径MTU发现配置

1
1
1
2009-09-08 11:41:12 +0000

参见 AdapterWatch

AdapterWatch 显示关于你的网络适配器的有用信息:IP地址、硬件地址、WINS服务器、DNS服务器、MTU值、接收或发送的字节数、当前的传输速度等。IP地址、硬件地址、WINS服务器、DNS服务器、MTU值、接收或发送的字节数、当前的传输速度等。此外,它还显示本地计算机的一般TCP/UDP/ICMP统计信息。