关于 Ping,你可能不知道的 12 个真相

6 阅读6分钟

用了十年 ping 命令,直到最近排障翻车才发现,我对它的理解一直停留在表面。整理 12 条容易被忽略的细节,每一条都踩过坑。

1. Ping 的名字来源于声呐

不是缩写,是拟声词。

1983 年 Mike Muuss 写出 ping 工具时,灵感来自潜艇声呐——发出一个 "ping" 声脉冲,听回声判断目标距离和方位。网络 ping 的逻辑一模一样:发一个包,等回包,算往返时间。

后来有人硬凑了个缩写叫 "Packet Internet Groper",Mike Muuss 本人公开吐槽过这是后人附会的。

2. Ping 用的不是 TCP 也不是 UDP

Ping 走的是 ICMP 协议,和 TCP/UDP 是平级的网络层协议,不是上下层。

这意味着:

  • Ping 不占端口(ICMP 没有端口概念)
  • 防火墙可以单独屏蔽 ICMP 而不影响 TCP/UDP 业务
  • 你 ping 不通的服务器,HTTP 请求可能完全正常

这是最常见的排障误判来源。

3. "Ping 通了"约等于什么都没证明

Ping 只能证明三件事:

  1. 你的网络层路由可达目标
  2. 目标主机的 ICMP 协议栈在工作
  3. 中间链路允许 ICMP 通过

不能证明:

  • 80/443/任何业务端口是开着的
  • 服务进程在运行
  • TCP 握手能成功
  • TLS 证书没过期
  • 应用层逻辑正常

下次有人说"我 ping 了没问题",你可以反问一句:你测端口了吗?

4. 很多服务器故意不响应 Ping

包括但不限于:

  • 微软的 microsoft.com(部分时期)
  • 大量云厂商的默认安全组屏蔽 ICMP
  • CDN 节点通常只响应业务流量,不响应 ICMP
  • 某些 CDN 后的源站完全屏蔽 ICMP 防扫描

所以 ping 不通某个网站,不代表它挂了。它只是不想理你。

5. Windows 和 Linux 的 ping 默认行为完全不同

行为WindowsLinux/macOS
默认次数4 次后停止无限循环(Ctrl+C 终止)
默认间隔1 秒1 秒
默认包大小32 字节56 字节(+8 字节 ICMP 头 = 64)

跨平台脚本调用 ping 时,参数和输出格式都不一样,这是踩坑重灾区。

6. TTL 不是时间,是跳数

TTL(Time To Live)字面是"存活时间",但实际单位是跳数,不是秒。

每经过一个路由器 TTL -1,减到 0 包就被丢弃。设计本意是防止路由环路导致包永久流转。

通过返回包的 TTL,可以反推目标系统:

返回 TTL目标系统大概率是
64 附近Linux / macOS / Unix
128 附近Windows
255 附近网络设备(路由器/交换机)

为什么是"附近"?因为初始 TTL 是这几个值,经过几跳就减几。比如收到 TTL=58,大概率是 Linux 系统经过了 6 跳。

这条在做资产识别和渗透测试时是基础知识。

7. Ping 的 RTT ≠ 单程延迟 × 2

RTT(Round Trip Time)是往返时间。直觉上你会以为单程延迟 = RTT/2,但这个等式经常不成立。

原因是网络是非对称路由的——去程和回程可能走完全不同的路径。

举个例子:

  • 你在上海,目标在美国西海岸
  • 去程:上海 → 香港 → 美西(30ms)
  • 回程:美西 → 日本 → 上海(50ms)
  • RTT = 80ms,但单程不是 40ms

这也是为什么在线游戏里有"我延迟 30ms 但对手打我感觉延迟 80ms"的情况——双方测的都是各自的 RTT。

8. 中间路由器对 ICMP 限速是默认行为

骨干网路由器处理 ICMP 的优先级远低于业务流量。

CPU 一忙,路由器会主动丢弃 ICMP 包来保证 TCP/UDP 转发性能。这导致:

  • traceroute 中间出现 * * * 不一定是链路断了
  • ping 大包丢包率高,小包正常,可能是中间节点限速
  • 业务流量完全正常,但 ping 显示丢包 30%

判断方法:用 TCPing 测业务端口,TCP 正常就说明 ICMP 丢包是限速导致的,不影响业务。

9. Ping 包大小会影响测试结果

默认 ping 是 32 或 64 字节小包,对网络压力极小。但实际业务流量包要大得多。

故意发大包能测出小包测不出来的问题:

# Linux 发 1472 字节的包(接近以太网 MTU 上限)
ping -s 1472 目标IP

# Windows 发 1472 字节
ping -l 1472 目标IP

# 测试是否有 MTU 问题(不分片)
ping -M do -s 1472 目标IP   # Linux
ping -f -l 1472 目标IP      # Windows

如果小包正常、大包丢包,大概率是路径上某段 MTU 不匹配,需要排查 PPPoE、VPN、隧道之类的封装。

10. 单地 Ping 出来的延迟,没有参考价值

你在公司 ping 服务器 20ms,能说明什么?

只能说明你这一条链路到目标 20ms。

但你的用户分布在全国各地、甚至海外,BGP 选路对每个出口 IP 都不一样:

  • 北京联通用户走的是一条路
  • 广州电信用户走的是另一条路
  • 海外用户走的是国际出口
  • 移动 4G 用户走的又不一样

单点测试得出"网络没问题"的结论,对其他地区用户的体验完全没参考意义

要做有价值的网络质量评估,必须多节点同时测。自己搭多节点环境成本太高,用现成的多地探测工具更实际,比如 BiuPing 这类在线工具支持从全国多个节点同时发起 Ping/TCPing/Traceroute,能直接对比各地结果,定位是全局问题还是区域问题。

11. ping -f 是个危险参数(Linux)

Linux 的 ping -f 是 flood ping,没有间隔地连续发包

ping -f 目标IP    # 需要 root 权限

正常 ping 默认 1 秒一个包,flood ping 是发完立刻发下一个。在带宽足够的情况下,每秒可以发几万个包。

用途:网络压力测试、检测高丢包率链路。

风险

  • 对目标可能造成 DoS 效果
  • 你的网络出口带宽可能瞬间打满
  • 在生产环境对线上服务器跑这个 = 找事

非测试环境绝对不要用。

Windows 的 ping -t 是持续 ping(带间隔),不是 flood ping,不要搞混。

12. ping 0 在某些系统上等同于 ping 本机

试一下:

ping 0

在 Linux 上,这会被解析为 127.0.0.1。原因是 IP 地址 0.0.0.0 在某些上下文里被内核当作"本机所有接口",路由层面会回环到 lo。

类似的还有:

  • ping 0.0.0.1 → Linux 上等价于 127.0.0.1(部分发行版)
  • ping 1 → 解析成 0.0.0.1,再被路由到本机
  • ping 2130706433 → 等价于 127.0.0.1(这是 127.0.0.1 的十进制整数形式)

Windows 不支持这种简写,会直接报无效地址。

实用价值不大,但写在自动化脚本里能装。

写在最后

ping 看起来是个十秒就能学会的命令,但真正用好它需要理解 ICMP 协议、TTL 机制、网络路径、协议栈实现差异这一整套底层知识。

排障的本质从来不是会用工具,而是知道工具的边界——它能测什么,不能测什么,结果应该怎么解读。

如果你的排障习惯还停留在"ping 一下看看",是时候升级了。