ping命令原理

进行网络通信时,我们经常需要判断一台主机是否活跃。

举个例子,alicebruce 进行通信之前,可以先 ping 一下他的 IP 地址 192.168.171.3 ,看主机是否有应答:

如果 alice 可以收到应答,说明主机是活跃的:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
root@alice [ ~ ]  ➜ ping -n 192.168.171.3
PING 192.168.171.3 (192.168.171.3) 56(84) bytes of data.
64 bytes from 192.168.171.3: icmp_seq=1 ttl=62 time=0.107 ms
64 bytes from 192.168.171.3: icmp_seq=2 ttl=62 time=0.404 ms
64 bytes from 192.168.171.3: icmp_seq=3 ttl=62 time=0.206 ms
64 bytes from 192.168.171.3: icmp_seq=4 ttl=62 time=0.298 ms
^C
--- 192.168.171.3 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3075ms
rtt min/avg/max/mdev = 0.107/0.253/0.404/0.109 ms

那么,ping 命令是如何工作的呢?掌握 ICMP 协议后,我们可以着手研究 ping 的通信过程了。

回显请求

没错!ping 命令正是利用 ICMP 协议来探测主机的,它通信过程很简单:

首先,探测方往被探测方发出类型为 8ICMP 回显请求echo request )报文;被探测方收到回显请求后,向探测方回复 回显应答echo reply )报文,类型为 0

注意到,ICMP 回显请求和回显响应报文,同样是作为数据搭载在 IP 包中进行网际旅行的。

ICMP 报文格式因类型而异,对于回显请求和回显响应报文,头部还有另外两个字段:

  • 标识符identifier ),辅助匹配回显请求和回显应答;
  • 序号sequence number ),辅助匹配回显请求和回显应答;

主机收到回显请求后,会将报文中的标识符和序号原封不动地在应答报文中返回。

由于系统可以同时执行多个 ping 命令进程,如何将应答与对应的进程进行匹配呢?

其实很简单,每个 ping 命令将自己的进程号作为标识符封装在回显请求报文中,目标主机会将标识符原封不动地在应答中返回,这样 ping 命令进程就可以区分出自己的应答了:

ping 命令通常每秒钟发出一个回显请求,然后在应答到达时计算每个请求的往返时间。当然了,回显请求也可能因中间路由丢包而超时。那么,怎么将请求和应答关联起来呢?

答案也很简单,ping 每次请求时可以分配一个自增序号,保存在报文序号字段中。目标主机对请求进行应答时,会将序号原封不动地返回。ping 命令收到应答后,就可以与自己发出的请求对应起来:

纸上得来终觉浅,绝知此事要躬行。

经过本节理论学习,我们虽然掌握了 ICMP 协议和 ping 命令的工作原理,但认识可能不是特别深入。下一小节,我们自己动手开发一个 ping 命令,彻底将理论知识吃透。

扩展阅读

小菜学网络】系列文章首发于公众号【小菜学编程】,敬请关注:

【小菜学网络】系列文章首发于公众号【小菜学编程】,敬请关注: