引言

Ping 程序是对两个 TCP/IP 系统连通性进行测试的基本工具。
它只利用 ICMP 回显请求和回显应答报文,而不用经过传输层(TCP/UDP)
----------------------------------------------------------------from《TCP/IP 详解 卷 1:协议》

根据描述,可以看出 ping 程序排错的原理得益于 ICMP 协议的报文,
因此学习 ICMP 协议就能了解 ping 程序为什么能排查网络问题。

第一部分:ICMP 协议

什么是 ICMP

位于网络层,封装在 IP 协议之内,ICMP 是控制报文协议。ICMP 允许主机或者设备报告差错和提供有关异常情况的报告,用来测试网络/设备的畅通情况。

ICMP 结构

-------------------------------------------------
| 类型 (Type) | 代码 (Code) | 校验和 (Checksum) |
-------------------------------------------------
| 标识符 (Identifier) | 序列号 (Sequence Number) |
-------------------------------------------------
| 数据 (Data)                                       |
-------------------------------------------------

ICMP 报文类型

ICMP 的报文分为两大类:差错报文和查询报文。错误报文的不同种情况都有不同的类型和代码值,是用于网络诊断的主要判别点。

<1> 查询报文

<2> 差错报文

ICMP 时间戳和 TTL

<1> Ping 程序中显示的时间

显示的时间为: 发送 ICMP Echo Request 到接收 ICMP Echo Reply 的往返时间
时间计算的原理:通过记录 Echo Request 请求 和 ICMP Echo Reply 回包的时间戳,再计算时间差得出。

以 ping 百度为例,用 wireshark 复现下:



图片中两个请求前后的时间差 0.091113000 - 0.079896000 = 0.011217000000000005
四舍五入后得到图片中的 11ms

<2> Ping 程序中显示的 TTL

TTL 是 ICMP 报文的一个重要字段,用来限制 ICMP 报文在网络中传播的最大跳数,防止报文在网络中无限循环。
TTL 每经过一个路由器就会-1,当未到达目的地,且 TTL=0 时,就会返回 TTL 为 0 的报错。
TTL 是在 ICMP 报文的 IP 头部字段,见下图:

在 Ping 程序中,显示的 ttl 值是 ICMP Echo Reply 中的 TTL 值


第二部分:Ping 程序指令查询

1.Windows 环境

 ping [选项] [IP地址或主机名]
 ping [-t] [-a] [-n count] [-l size] [-f] [-i TTL] [-v TOS]
            [-r count] [-s count] [[-j host-list] | [-k host-list]]
            [-w timeout] [-R] [-S srcaddr] [-c compartment] [-p]
            [-4] [-6] target_name


===========参数说明=======================
-t             Ping 指定的主机,直到停止。
               若要查看统计信息并继续操作,请键入 Ctrl+Break;
               若要停止,请键入 Ctrl+C。
-a             将地址解析为主机名。
-n count       要发送的回显请求数。
-l size        发送缓冲区大小。
-f             在数据包中设置“不分段”标记(仅适用于 IPv4)。
-i TTL         生存时间。
-v TOS         服务类型(仅适用于 IPv4。该设置已被弃用,
               对 IP 标头中的服务类型字段没有任何
               影响)。
-r count       记录计数跃点的路由(仅适用于 IPv4)。
-s count       计数跃点的时间戳(仅适用于 IPv4)。
-j host-list   与主机列表一起使用的松散源路由(仅适用于 IPv4)。
-k host-list   与主机列表一起使用的严格源路由(仅适用于 IPv4)。
-w timeout     等待每次回复的超时时间(毫秒)。
-R             同样使用路由标头测试反向路由(仅适用于 IPv6)。
               根据 RFC 5095,已弃用此路由标头。
               如果使用此标头,某些系统可能丢弃
               回显请求。
-S srcaddr     要使用的源地址。
-c compartment 路由隔离舱标识符。
-p             Ping Hyper-V 网络虚拟化提供程序地址。
-4             强制使用 IPv4。
-6             强制使用 IPv6。


2.Linux 环境

 ping [参数] [IP地址或主机名]
 ping [-LRUbdfnqrvVaAD] [-c count] [-i interval] [-w deadline]
     [-p pattern] [-s packetsize] [-t ttl] [-I interface]
     [-M pmtudisc-hint] [-m mark] [-S sndbuf]
     [-T tstamp-options] [-Q tos] [hop1 ...] destination

===========参数说明=======================
-d     使用Socket的SO_DEBUG功能。
-f     极限检测。大量且快速地送网络封包给一台机器,看它的回应。
-n     只输出数值。
-q     不显示任何传送封包的信息,只显示最后的结果。
-r     忽略普通的Routing Table,直接将数据包送到远端主机上。通常是查看本机的网络接口是否有问题。
-R     记录路由过程。
-v     详细显示指令的执行过程。
-c    数目:在发送指定数目的包后停止。
-i     秒数:设定间隔几秒送一个网络封包给一台机器,预设值是一秒送一次。
-I     网络界面:使用指定的网络界面送出数据包。
-l     前置载入:设置在送出要求信息之前,先行发出的数据包。
-p     范本样式:设置填满数据包的范本样式。
-s     字节数:指定发送的数据字节数,预设值是56,加上8字节的ICMP头,一共是64ICMP数据字节。
-t     存活数值:设置存活数值TTL的大小。

第三部分:网络排查和排错

Ping 的主要作用

写了一点发现了篇很好的网络排错文章,就不想写了,果然专业的事还得专业的人写😈
链接如下:
https://cloud.tencent.com/developer/article/2394150


↙↙↙阅读原文可查看相关链接,并与作者交流