进行网络通信时,我们经常需要判断一台主机是否活跃。
举个例子,alice 跟 bruce 进行通信之前,可以先 ping 一下他的 IP 地址 192.168.171.3 ,看主机是否有应答:
如果 alice 可以收到应答,说明主机是活跃的:
|
|
那么,ping 命令是如何工作的呢?掌握 ICMP 协议后,我们可以着手研究 ping 的通信过程了。
回显请求
没错!ping 命令正是利用 ICMP 协议来探测主机的,它通信过程很简单:
首先,探测方往被探测方发出类型为 8 的 ICMP 回显请求( echo request )报文;被探测方收到回显请求后,向探测方回复 回显应答 ( echo reply )报文,类型为 0 。
注意到,ICMP 回显请求和回显响应报文,同样是作为数据搭载在 IP 包中进行网际旅行的。
ICMP 报文格式因类型而异,对于回显请求和回显响应报文,头部还有另外两个字段:
- 标识符( identifier ),辅助匹配回显请求和回显应答;
- 序号( sequence number ),辅助匹配回显请求和回显应答;
主机收到回显请求后,会将报文中的标识符和序号原封不动地在应答报文中返回。
由于系统可以同时执行多个 ping 命令进程,如何将应答与对应的进程进行匹配呢?
其实很简单,每个 ping 命令将自己的进程号作为标识符封装在回显请求报文中,目标主机会将标识符原封不动地在应答中返回,这样 ping 命令进程就可以区分出自己的应答了:
ping 命令通常每秒钟发出一个回显请求,然后在应答到达时计算每个请求的往返时间。当然了,回显请求也可能因中间路由丢包而超时。那么,怎么将请求和应答关联起来呢?
答案也很简单,ping 每次请求时可以分配一个自增序号,保存在报文序号字段中。目标主机对请求进行应答时,会将序号原封不动地返回。ping 命令收到应答后,就可以与自己发出的请求对应起来:
纸上得来终觉浅,绝知此事要躬行。
经过本节理论学习,我们虽然掌握了 ICMP 协议和 ping 命令的工作原理,但认识可能不是特别深入。下一小节,我们自己动手开发一个 ping 命令,彻底将理论知识吃透。
扩展阅读
【小菜学网络】系列文章首发于公众号【小菜学编程】,敬请关注: