localhost在某些情况下无法访问的问题
   日常工作    0 comment
localhost在某些情况下无法访问的问题
   日常工作    0 comment

发现问题

事情起因是今天我在调试本机的一个http服务的时候发现localhost始终无法访问,但项目控制台有响应的打印信息。与此同时,我的前端本地项目却能正确访问,这就让人有点百思不得其解了。

首先我ping了本机ip: 127.0.0.1localhost,结果却不一样。localhost被解析成了:[::1]

//127.0.0.1
正在 Ping xxz [127.0.0.1] 具有 32 字节的数据:
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128

//localhost
正在 Ping xxz [localhost] 具有 32 字节的数据:
来自 [::1] 的回复: 字节=32 时间<1ms TTL=128
来自 [::1] 的回复: 字节=32 时间<1ms TTL=128
来自 [::1] 的回复: 字节=32 时间<1ms TTL=128
来自 [::1] 的回复: 字节=32 时间<1ms TTL=128

然后我先用netstat -ano检查一下一下本机的端口占用情况,然后用命令行netstat -aon|findstr "3000"查找有关‘3000’的信息

结果如下:

  TCP    127.0.0.1:53000        0.0.0.0:0              LISTENING       8312
  TCP    [::1]:3000             [::]:0                 LISTENING       936

后又通过PID 936用tasklist|findstr "936"查询占用端口的进程:

wininit.exe                   1160 Services                   0      5,936 K
fontdrvhost.exe               1520 Console                    1     10,936 K
http.exe                       936 Console                    1      6,340 K

http.exe正是我在本地开启的无法访问的服务了,我监听的是localhost:3000,这里却显示TCP [::1]:3000,这时我使用该地址在浏览器访问,页面成功加载出来了。但问题仍需解决,经过查找发现,[::1]是IPV6的地址格式,造成这种情况的原因是本机的IP优先级设置IPV6 > IPV4,接下来的就是要解决优先级设定的问题了。

解决问题

1. 查看本机Ip优先级

使用终端(管理员)命令行工具,输入命令 netsh interface ipv6 show prefixpolicies 查看IPv6优先级。

优先顺序    标签   前缀
----------  -----  --------------------------------
        50      1  ::/0
        45      2  ::1/128
        40      3  ::/96
        35      4  ::ffff:0:0/96
        30      5  2002::/16
        30      3  2001::/32
         3     13  fc00::/7
         1     12  3ffe::/16
         1     11  fec0::/10

代表ipv6的::/0和::1/128的优先级高于表示ipv4的::/96和::ffff:0:0/96。

2. 重新设置ipv6的优先级

通过一系列命令重设ip的优先级:

netsh int ipv6 set prefix ::/96 50 0
netsh int ipv6 set prefix ::ffff:0:0/96 40 1
netsh int ipv6 set prefix 2002::/16 35 2
netsh int ipv6 set prefix 2001::/32 30 3
netsh int ipv6 set prefix ::1/128 10 4
netsh int ipv6 set prefix ::/0 5 5
netsh int ipv6 set prefix fc00::/7 3 13
netsh int ipv6 set prefix fec0::/10 1 11
netsh int ipv6 set prefix 3ffe::/16 1 12

再次用命令 netsh interface ipv6 show prefixpolicies查看ip的优先级,发现设置已经生效:

优先顺序    标签   前缀
----------  -----  --------------------------------
        50      0  ::/96
        40      1  ::ffff:0:0/96
        35      2  2002::/16
        30      3  2001::/32
        10      4  ::1/128
         5      5  ::/0
         3     13  fc00::/7
         1     12  3ffe::/16
         1     11  fec0::/10

3. 测试localhost的接通性

再次ping 127.0.0.1和localhost,结果如下:二者都指向了ipv4的127.0.0.1。至此重新使用localhost:3000在浏览器成功访问项目。

//127.0.0.1
正在 Ping xxz [127.0.0.1] 具有 32 字节的数据:
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128

//localhost
正在 Ping xxz [localhost] 具有 32 字节的数据:
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128
来自 127.0.0.1 的回复: 字节=32 时间<1ms TTL=128

补充

::/0,默认路由条目,不用于寻址;
::/128,未指定地址, 可作为源IP地址使用;
::1/128,IPv6主机回送地址,不用于发送出本地主机的数据中;
::ffff:0:0/96,IPv4映射地址, 这种地址不会出现在分组头部,只用于内部主机;
::{ipv4-address}/96,IPv4兼容地址,已过时,未使用;
2001::32,Teredo地址;
2001:10::/28,ORCHI(覆盖可路由加密散列标识符),这种地址不会出现在公共的Internet中;
2001:db8::32,用于文档和实例的地址范围,这种地址不会出现在公共的Internet中;
2002::16,6to4隧道中继的6to4地址;
3ffe::/16,用于6bone实验,已过时,未使用;
5f00::/16,用于6bone实验, 已过时,未使用;
fc00::/7,唯一的本地单播地址,不用于全球性的Inrternet;
fe80::/10,链路本地单播地址;
ff00::/8,IPv6组播地址, 仅为目的地址使用。

Responses