ping命令的使用与实现原理剖析

2,577 阅读4分钟

ping简介

在诊断网络问题时,我们经常会使用ping命令。它可以快速告诉我们,某个域名是否可以可以访问,访问延时高不高。

虽然在网络日益复杂的今天,一台主机是否能够ping通,跟该主机是否能够连接上并没有必然的联系,但很多时候还是能够帮助我们发现不少的问题。

举个例子,广大IT群众最喜欢用百度来测试网络情况,用的就是ping。

➜  ~ ping www.baidu.com
PING www.a.shifen.com (14.215.177.38): 56 data bytes
64 bytes from 14.215.177.38: icmp_seq=0 ttl=55 time=7.146 ms
64 bytes from 14.215.177.38: icmp_seq=1 ttl=55 time=7.228 ms
64 bytes from 14.215.177.38: icmp_seq=2 ttl=55 time=7.018 ms
64 bytes from 14.215.177.38: icmp_seq=3 ttl=55 time=7.243 ms
^C
--- www.a.shifen.com ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 7.018/7.159/7.243/0.089 ms

ping输出分析

前面例子中,ping输出的内容包含三部分:

输出一:ping的主机对应的IP地址(进行了DNS解析),向该主机发送的数据包的大小(56字节)。

PING www.a.shifen.com (14.215.177.38): 56 data bytes

输出二:来自主机的响应信息。

  • icmp_seq:序列号,表示第几个个响应包(递增的数字)。
  • time:请求往返耗时。
  • ttl:IP数据报的ttl设置。
  • 64 bytes:响应的数据包大小是64字节。
64 bytes from 14.215.177.38: icmp_seq=0 ttl=55 time=7.146 ms
64 bytes from 14.215.177.38: icmp_seq=1 ttl=55 time=7.228 ms
64 bytes from 14.215.177.38: icmp_seq=2 ttl=55 time=7.018 ms
64 bytes from 14.215.177.38: icmp_seq=3 ttl=55 time=7.243 ms

输出三:ping整体请求/响应概览。

  • 一共发送了4个ping请求,收到4个ping响应,丢包率是0%。
  • 最小/平均/最大往返时间:7.018/7.159/7.243 ms。
--- www.a.shifen.com ping statistics ---
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 7.018/7.159/7.243/0.089 ms

实现原理

ping命令主要基于ICMP(Internet Control Message Protocol)实现,它包含了两部分:客户端、服务器。

  • 客户端:向服务端发送ICMP回显请求报文(echo message)。
  • 服务端:向客户端返回ICMP回西显响应报文(echo reply message)。

ICMP报文通用格式如下:

  • 类型:1个字节。8表示回显请求报文,0表示回显响应报文。
  • 代码:1个字节。回显请求报文、回显响应报文 时均为0。
  • 校验和:2个字节。非重点,略过。
  • 标识符:2个字节。发送ICMP报文的客户端进程的id,服务端会回传给客户端。因为同一个客户端可能同时运行多个ping程序,这样客户端收到回西显报文,可以知道是响应给哪个客户端进程的。
  • 序列号:2个字节。从0开始,客户端每次发送新的回显请求时+1。服务端原样会传。
  • 数据:6个字节。客户端记录回显请求的发送时间,服务端记录回西显响应的发送时间

wireshark抓包分析

以前面ping百度为例,下面是wireshark的抓包截图。可以看到,包含了4组请求、响应。

看下第1个回显请求。类型为8,代码为0,序列号为0,标识符为发送进程的id。

再看下第1个回显响应。类型为0,代码为0,序列号、标识符与回显请求的一致。

最后看下回显请求->响应的耗时间。请求发送时间为 May 13, 2018 18:59:14.022371000 CST,请求->响应的往返耗时为 7.092毫秒。

其他3组数据可参照上面的方法进行分析。

写在后面

ping是很常用的网络监测手段,开发者有必要掌握它的用法,以及懂得如何分析它的输出结果。

此外,对于时长需要跟网络打交道的开发者来说,最好还能掌握ping的实现原理,这样在遇到棘手的网络问题时,能够有更清晰的解决问题的思路。

比如,因为不恰当的设置,导致云主机服务能正常访问,但却死活ping不通,这个时候对实现细节的了解就派上用场了。

最后,文章内容如有错漏,敬请指出。

相关链接

Echo or Echo Reply Message
tools.ietf.org/html/rfc792

关于作者:程序猿小卡,前腾讯高级工程师,现任前海云汉金融科技前端技术负责人。专注技术架构、技术分享、项目管理。