如何判断 Windows XP 中正在使用的 MTU

如何判断 Windows XP 中正在使用的 MTU

我遇到了一个非常奇怪的问题,当我尝试访问网页时,随机收到“与服务器的连接已重置”错误(根据 Windows 网络诊断工具,HTTP 错误为 12031)——无论我尝试访问的网页是在外部互联网上,还是来自在本地主机上运行的本地 Apache 实例,都会发生这种情况。它会影响我们本地网络(以太网,不是无线)上的所有计算机,所有这些计算机都运行 Windows XP。

有人告诉我,这可能与网络流量使用的 MTU 有关。如果我Ping 测试为了找出可以不分段通过的最大数据包,我可以用 1492 字节的数据包(加上 28 字节的报头?)ping 本地主机,也可以用 1462 字节的数据包(加上 28 字节的报头就是 1490 字节)ping 我们的路由器。如果我尝试 ping 外部的某个东西,比如 Google,我无法让任何大于 1430(加上报头就是 1458)的东西通过。

我尝试按照各种说明更新 Windows XP 注册表,使用此 MTU 设置,更新HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{AdapterID}\MTU。我尝试了无数个备选值:最明显的正确值似乎是 1490,但我也尝试了 1462、1458、1430 等。当我重新启动计算机以使更改生效时,它似乎工作几分钟(很难确定,因为它总是随机的而不是一致的)但它不会持续很长时间。

最初,当我尝试使用 1430 作为值时,经过几分钟的正常工作后,Ping 测试的结果会减少 28 个字节 - 突然我发现我只能将 1402 字节的包发送到 Google。如果我将 MTU 注册表设置更新为 1402,当我重新启动并等待几分钟时,它会变成 1374,然后是 1346,等等。网络上的其他计算机不受影响(仍为 1430),从注册表中删除 MTU 设置将恢复正常(但仍然出现故障)。

我发现诊断这一切最困难的事情是,很难判断我是否使用了正确的注册表设置。所以最简单的问题是:我如何知道 Windows 正在尝试使用什么 MTU 设置?

此外,如果有人知道如何判断为什么 MTU 不断下降 28,这也会很有用(例如,是否存在 Windows 日志文件,它会在值发生变化时记录某些内容?)

最后,如果有人能明确地告诉我如何判断我应该尝试使用什么 MTU 设置,那就太好了!

答案1

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

Windows 7、Windows Vista

显示当前最大传输单元在 Windows 7 或 Windows Vista 上,从命令提示符:

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.

已使用 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 不提供从 内部更改 MTU 设置的方法netsh。为此,您可以:

已使用 Windows XP Service Pack 3 进行测试

也可以看看


简要讨论一下 MTU 是什么以及这 28 个字节来自哪里。

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

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

IP 部分TCP/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

然后产生的以太网数据包将满到无底洞。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.

数据包需要分片,但不要分裂已设置标志。

如果在线路的任何地方需要对数据包进行分段,网络实际上会发送一个 ICMP 数据包,告诉您发生了分段。您的计算机会收到此 ICMP 数据包,并被告知最大大小是多少,并且应该停止发送过大的数据包。不幸的是,大多数防火墙都会阻止这些“路径 MTU 发现”ICMP 数据包,因此您的计算机永远不会意识到数据包正在被分段(或更糟:因为无法分段而被丢弃)。

这就是导致 Web 服务器无法工作的原因。您可以获得初始的较小(<1280 字节)响应,但较大的数据包无法通过。并且 Web 服务器的防火墙配置错误,阻止了 ICMP 数据包。因此 Web 服务器没有意识到您从未收到过数据包。

IPv6 不允许数据包分段,每个人都是必需的(正确地)允许 ICMP mtu 发现数据包。

答案2

@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 上,你必须使用反复试验的方法不碎裂标记来查找您可以发送的最大数据包。然后您就得到了 MTU。

答案3

您可以使用 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”消息。

答案4

Microsoft KB314496:不同网络拓扑的默认 MTU 大小
您不应尝试在正常网络设置中使用 MTU 配置。

有一个VB代码参考这里还有
一个工具叫德克萨斯

替代文本


在注册表中,

  • HKLM\Software\Microsoft\Windows NT\CurrentVersion\NetworkCards
  • 打开您感兴趣的适配器
  • 复制ServiceName字符串
  • 搜索该字符串HKLM\System;您将匹配一个NetCfgInstanceId
  • 略高于这个数字就是MaxFrameSize关键(我的显示为 1514)

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

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

相关内容