Ping的基本原理

ping主要用于测试网络层的连通性和往返时延(RTT round trip time)。它基于ICMP协议工作,通常使用:

  • ICMP Echo Request(Type=8):请求报文
  • ICMP Echo Reply(Type=0):响应报文
  • IPv4下协议号:1(ICMP)
  • IPv6下使用ICMPv6,类型不同

以IPv4为例:

1
2
3
4
5
6
7
主机A                                      主机B
| |
|--- ICMP Echo Request ------------------> |
| |
|<-- ICMP Echo Reply --------------------- |
| |
| 计算往返时间RTT |

例如执行:

1
ping 192.168.1.100

主机A会向192.168.1.100发送ICMP Echo Request。如果B收到且允许响应,就返回ICMP Echo Reply。


1.Ping报文在协议栈中的位置

Ping本身不是TCP或UDP应用层协议,而是直接使用IP层之上的ICMP:

1
2
3
4
5
6
7
8
9
┌─────────────────────────┐
│ Ethernet帧 │
├─────────────────────────┤
│ IPv4 Header │
├─────────────────────────┤
│ ICMP Header │
├─────────────────────────┤
│ ICMP Data/Payload │
└─────────────────────────┘

因此可以理解为:

1
2
3
4
5
6
7
Ethernet
↓
IP
↓
ICMP
↓
Echo Request / Echo Reply

ICMP虽然通常被称为“网络层协议”,但从报文封装关系来看,它位于IP之上、TCP/UDP旁边。


2.ICMP报文

IPv4下,Echo Request的ICMP报文格式:

1
2
3
4
5
6
7
8
9
0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Type | Code | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identifier | Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

3.Ping为什么能够判断网络是否连通

假设:

1
A → B

A发送:

1
ICMP Echo Request

如果B能够收到,并且B的系统允许响应:

1
B → A

返回:

1
ICMP Echo Reply

那么至少可以证明:

  1. A能够向B发送IP数据包;
  2. B能够收到该数据包;
  3. B能够生成ICMP响应;
  4. B到A的返回路径可用;
  5. 中间网络设备没有阻止该ICMP报文。

因此Ping成功通常意味着:

1
A ←→ B

之间的IP层路径基本可达。但Ping失败不一定意味着主机不可达,因为防火墙可以专门丢弃ICMP Echo Request/Reply。


4.Ping过程总结

把整个过程串起来就是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
ping 192.168.1.100
│
▼
确定目标IP
│
▼
判断是否需要经过网关
│
├── 同网段 → ARP获取目标MAC
│
└── 跨网段 → ARP获取网关MAC
│
▼
构造IPv4数据报
│
▼
Protocol=1(ICMP)
│
▼
ICMP Echo Request
Type=8,Code=0
│
▼
网络传输
│
▼
目标主机收到Request
│
▼
构造ICMP Echo Reply
Type=0,Code=0
│
▼
返回发送端
│
▼
计算RTT和统计结果

最核心的一句话:

Ping就是发送ICMP Echo Request(Type=8),目标主机返回ICMP Echo Reply(Type=0),发送端根据Sequence Number匹配请求与响应,并根据发送/接收时间计算RTT。