⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 juejin.cn/post/7129350312720072734 「丘山子」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注**微信公众号:【芋道源码】**有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言将得到认真回复。甚至不知道如何读源码也可以请教噢
  4. 新的源码解析文章实时收到通知。每周更新一篇左右
  5. 认真的源码交流微信群。

你知道ping命令是如何工作的吗?

我们用来测试一台机器与另一台机器的网络连通性一般会使用ping命令,那么你知道ping命令是如何工作的吗?ping命令是基于ICMP协议工作的。

一、介绍ICMP协议

因特网控制报文协议ICMP(Internet Control Message Protocol)是一个**「差错报告机制」**,其主要用在IP机器与路由器之间传递控制信息,其一般用于报告主机是否可达、路由是否可用。

二、为什么需要ICMP?

在网络数据包的传输过程中,经常会遇到各种各样的问题,IP协议提供Best-Effort(尽力而为)的服务,尽力而为的意思是当网络发生拥塞的时候,会立刻丢弃网络数据包,一直到网络拥塞现象减轻时。所以经常有些数据包中途被丢弃,可能还有其他更多的问题,所以需要网络数据包在出现问题时,机器向上层协议报告异常,以便进行流量控制和差错控制,使用ICMP就可以实现这一功能。

三、ICMP的格式

ICMP的格式

上图是ICMP的格式,IP数据报由IP头和ICMP报文组成。ICMP报文由8位的类型、8位的代码、16位的校验和ICMP都数据部分组成。

ICMP的数据部分根据类型和代码不同而不同,如果是请求与响应的数据包,那么数据部分由16位的标识符、16位的序号以及数据组成。如果是差错报文,那么数据部分由两个16位的unused部分和IP头、8字节的正文组成。

ICMP报文分类大家可以看华为的文档,我这里不在叙述:《什么是ICMP?ICMP如何工作?》https://info.support.huawei.com/info-finder/encyclopedia/zh/ICMP.html

四、查询报文

我们的ping命令就是查询报文,如果一切顺利,我们发送8.echo请求,然后会收到0.echo响应,这就证明两机器之间是连通的。

但是这个数据包比原生的ICMP,多了两个字段——标识符、序号。

怎么理解呢?如果你搞过装修,你应该知道建材店之间组成的销售联盟,联盟派出去两拨人,一批是跑业务的,一批是做广告的,都穿着同样的广告衫,需要一个标识区分这两批人。而派出去的人需要编号,如果到了吃午饭的时间,出去跑业务的20个人回来一小部分,说明情况不妙,如果全部回来,说明情况很好。

在**「选项数据」**中,ping 还会存放发送请求的时间值,来计算往返时间,说明路程的长短。

五、差错报文

根据《什么是ICMP?ICMP如何工作?》https://info.support.huawei.com/info-finder/encyclopedia/zh/ICMP.html这篇文章我们可以了解下面几种常见的ICMP差错报文:

  • 3-目的不可达
  • 4-原点抑制消息
  • 11-ICMP超时
  • 5-重定向

3-目的不可达

当类型3目的不可达,有以下几种常见代码:

Code 描述 查询/差错
0 目标网络不可达报文 差错
1 目标主机不可达报文 差错
2 目标协议不可达报文 差错
3 目标端口不可达报文 差错
4 要求分段并设置DF flag标志报文 差错

出现目标网络不可达报文的情况是数据包到达路由器,但是路由表中没有数据包中IP地址的网络号。

目标主机不可达报文是路由器中没有找到目标主机的信息,也有可能是目标主机没有连接到网络。

目标协议不可达报文情况当你给目标主机发送UDP报文时,目标主机的防火墙禁止UDP协议数据包进入,于是ICMP通知目标协议不可达。

目标端口不可达报文是你的数据包要进入目标主机的22端口,建立SSH连接,而目标主机的22端口没有开放,这时候ICMP就会返回目标端口不可达报文给源主机。

要求分段并设置DF flag标志报文`的情况如下:源主机发送的IP数据包首部的**「分片禁止标志位」**设置为1之后,路由器遇到超过MTU大小的数据包会直接抛弃,不会分片,然后ICMP给源主机发送`要求分段并设置DF flag标志报文

4-原点抑制消息

如果网络中遇到拥塞,就能向源主机发送一个ICMP原点抑制消息,收到该消息的机器就会增大数据包的传输间隔。是为原点抑制。

11-ICMP超时

为了限制IP数据包在计算机网络中的存在的时间,我们给数据包设计一个值TTL,能够避免IP包在网络中的无限循环和收发,节省了网络资源。

但是为了能使IP包的发送者能收到告警消息,ICMP开始大显身手,路由器会发送一个 ICMP **「超时消息」**给源主机。

5-重定向

如若路由器发现源主机不是使用**「最优路径」**发送数据,路由器就会发送重定向消息给源主机。

六、ping 的发送和接收过程

我们使用ping命令去请求同一个子网的目的主机。

1. 向目的主机发送回显请求

首先,机器会构建一个类型为8、代号为0的Echo请求报文。

向目的主机发送回显请求

通过上图,我们可以了解,ICMP的类型是8,代码是0等数据。

2. 目的服务器发送回显应答

目的服务器发送回显应答

通过比较,我们可以看到在ICMP报文层,Echo请求报文与Echo响应报文除了Type、Code(看起来没变化,其实含义已经不同)发生变化,其他基本上都是一样的。

ICMP报文

3. 源主机显示相关信息

源主机显示相关信息

源主机显示相关信息

发送回显请求数据包的时间,与接收到回显应答数据包的时间差,就能计算出数据包一去一回所需要的时间。

七、ICMP—Traceroute命令

Traceroute能够利用ICMP的规则,故意制造一些产生错误的场景。

Traceroute 的第一个作用为**「故意设置特殊的 TTL,来追踪去往目的地时沿途经过的路由器。」**

思路很骚啊~我给你慢慢道来:

先设置TTL为1,数据包到第一个路由器就嗝屁,临死前把第一个路由器的IP搞到手了。返回时间超时的ICMP差错报文。

然后设置TTL为2,数据包到第二个路由器嗝屁,临死前把第二个路由器的IP搞到手。

再设置TTL为3...

以此类推,直到到达目的主机,如此就拿到了线路上所有路由器的IP。

那么Traceroute怎么知道自己发送的UDP包到达目的主机呢?

思路也很骚啊!!!

它用不可能出现的值作为UDP的端口号,数据报达到目的主机,就会返回ICMP 差错报文,类型为端口不可达。

「Traceroute 还有一个作用是故意设置不分片,从而确定路径的 MTU。」

这个很容易想到啊,一旦返回类型为“需要进行分片但设置了不分片位”的ICMP差错报文就减小分组长度,直到达到目的主机,这不就测试出了整个路径的MTU吗?

好家伙好家伙,思路真棒!点赞!别忘了给咱家点个赞啊!

文章目录
  1. 1. 你知道ping命令是如何工作的吗?
  2. 2. 一、介绍ICMP协议
  3. 3. 二、为什么需要ICMP?
  4. 4. 三、ICMP的格式
  5. 5. 四、查询报文
  6. 6. 五、差错报文
    1. 6.1. 3-目的不可达
    2. 6.2. 4-原点抑制消息
    3. 6.3. 11-ICMP超时
    4. 6.4. 5-重定向
  7. 7. 六、ping 的发送和接收过程
    1. 7.1. 1. 向目的主机发送回显请求
    2. 7.2. 2. 目的服务器发送回显应答
    3. 7.3. 3. 源主机显示相关信息
  8. 8. 七、ICMP—Traceroute命令