第十八篇:一文说清楚ICMP的底层原理
作为程序员或者网络工程师,有时候无法访问对方主机;导致这个现象的有很多原因,那要排查具体的网络原因,可能会用到ping的指令。而ping的底层实现是互联⽹控制报⽂协议(ICMP)。
ICMP 全称是 Internet Control Message Protocol,也就是互联⽹控制报⽂协议。
-
ICMP 功能都有啥?
ICMP 主要的功能包括:
① 确认 IP 包是否成功送达⽬标地址
② 报告发送过程中 IP 包被废弃的原因和改善⽹络设置等。
在 IP 通信中如果某个 IP 包因为某种原因未能达到⽬标地址,那么这个具体的原因将由 ICMP 负责通知。
注意:
① ICMP是基于IP协议工作的,但是它并不是传输层的功能,因此人们仍把它归结于网络层协议。
② ICMP只能搭配IPv4使用。如果是IPv6的情况下,需要使用ICMPv6。

如上图例⼦,主机 A 向主机 B 发送了数据包,由于某种原因,途中的路由器 2 未能发现主机 B 的存在,这时,路由器 2 就会向主机 A 发送⼀个 ICMP ⽬标不可达数据包,说明发往主机 B 的包未能成功。
ICMP 的这种通知消息会使⽤ IP 进⾏发送。
因此,从路由器 2 返回的 ICMP 包会按照往常的路由控制先经过路由器 1 再转发给主机 A 。收到该 ICMP包的主机 A 则分解 ICMP 的⾸部和数据域以后得知具体发⽣问题的原因。
-
ICMP报文格式

说明:
① 类型:1字节,说明该报文属于什么类型。
② 代码:1字节,说明ICMP报文的代码。
③ 检验和:2字节,检验ICMP报文是否有错误。
ICMP 包头的类型字段,⼤致可以分为两⼤类:

① 「查询报⽂类型」
ICMP协议报文里面的类型是0和8的时候,说明这是一个查询报⽂。

可以向对端主机发送回送请求的消息( ICMP Echo Request Message ,类型 8 ),也可以接收对端主机发回来的回送应答消息( ICMP Echo Reply Message ,类型 0 )。这里的回送就是有来有回的意思。
② 「差错报⽂类型」
ICMP协议报文里面的类型不是0和8的时候,说明这是一个差错报⽂。

目标不可达:
IP 路由器⽆法将 IP 数据包发送给⽬标地址时,会给发送端主机返回⼀个⽬标不可达的 ICMP 消息,并在这个消息 中显示不可达的具体原因,原因记录在 ICMP 包头的代码字段。
举例 6 种常⻅的⽬标不可达类型的代码:

a. ⽹络不可达
IP 地址是分为⽹络号和主机号的,所以当路由器中的路由器表匹配不到接收⽅ IP 的⽹络号,就通过 ICMP 协议以网络不可达( Network Unreachable )的原因告知主机。
b. 主机不可达
当路由表中没有该主机的信息,或者该主机没有连接到⽹络,那么会通过 ICMP 协议以主机不可达( Host Unreachable )的原因告知主机。
c. 协议不可达
当主机使⽤ TCP 协议访问对端主机时,能找到对端的主机了,可是对端主机的防⽕墙已经禁⽌ TCP 协议访问,那么会通过 ICMP 协议以协议不可达的原因告知主机。
d. 端⼝不可达
当主机访问对端主机 8080 端⼝时,这次能找到对端主机了,防⽕墙也没有限制,可是发现对端主机没有进程监听8080 端⼝,那么会通过 ICMP 协议以端⼝不可达的原因告知主机。
e. 需要进⾏分⽚但设置了不分⽚
发送端主机发送 IP 数据报时,将 IP ⾸部的分⽚禁⽌标志位设置为 1 。根据这个标志位,途中的路由器遇到超过MTU ⼤⼩的数据包时,不会进⾏分⽚,⽽是直接抛弃。
原点抑制消息(ICMP Source Quench Message):
在使⽤低速⼴域线路的情况下,连接 WAN 的路由器可能会遇到⽹络拥堵的问题。
ICMP 原点抑制消息的⽬的就是为了缓和这种拥堵情况。当路由器向低速线路发送数据时,其发送队列的缓存变为零⽽⽆法发送出去时,可以向 IP 包的源地址发送⼀个 ICMP 原点抑制消息。
收到这个消息的主机借此了解在整个线路的某⼀处发⽣了拥堵的情况,从⽽增⼤ IP 包的传输间隔,减少⽹络拥堵的情况。 然⽽,由于这种 ICMP 可能会引起不公平的⽹络通信,⼀般不被使⽤。
重定向消息(ICMP Redirect Message):
如果路由器发现发送端主机使⽤了「不是最优」的路径发送数据,那么它会返回⼀个 ICMP 重定向消息给这个主机。
在这个消息中包含了最合适的路由信息和源数据。这主要发⽣在路由器持有更好的路由信息的情况下。路由器会通过这样的 ICMP 消息告知发送端,让它下次发给另外⼀个路由器。
超时消息(ICMP Time Exceeded Message):
IP 包中有⼀个字段叫做 TTL ( Time To Live ,⽣存周期),它的值随着每经过⼀次路由器就会减 1,直到减到 0 时该 IP 包会被丢弃。
此时,路由器将会发送⼀个 ICMP 超时消息给发送端主机,并通知该包已被丢弃。
设置 IP 包⽣存周期的主要⽬的,是为了在路由控制遇到问题发⽣循环状况时,避免 IP 包⽆休⽌地在⽹络上被转发。
此外,有时可以⽤ TTL 控制包的到达范围,例如设置⼀个较⼩的 TTL 值。
- ping命令
ping的报文格式:

相⽐原⽣的 ICMP,这⾥多了两个字段:
① 标识符:⽤以区分是哪个应⽤程序发 ICMP 包,⽐如⽤进程 PID 作为标识符;
② 序号:序列号从 0 开始,每发送⼀次新的回送请求就会加 1 , 可以⽤来确认⽹络包是否有丢失。
使用方法:
ping + 域名或IP
ping命令执行细节:

① ping命令会发送一个ICMP Echo Request给对端;

每发出⼀个请求数据包,序号会⾃动加 1 。为了能够计算往返时间 RTT ,它会在报⽂的数据部分插⼊发送时间。
ICMP报文被ICMP协议的实现程序组织好后,交给网络层的程序处理,加上源地址IP与目的IP,再传给数据链路层,加上源MAC地址与目的MAC地址;然后发送出去

说明:源和目的IP为上图的IP
② 对端接收后,返回一个ICMP Echo Reply;
③ 注意是在主机A网络层发出ICMP Echo Request,在主机B接收到网络层,再发出ICMP Echo Reply;

在规定的时候间内,源主机如果没有接到 ICMP 的应答包,则说明⽬标主机不可达;如果接收到了 ICMP 回送响应消息,则说明⽬标主机可达。
此时,源主机会检查,⽤当前时刻减去该数据包最初从源主机上发出的时刻,就是 ICMP 数据包的时间延迟。
针对上⾯发送的事情,总结成了如下图:

当然这只是最简单的,同⼀个局域⽹⾥⾯的情况。如果跨⽹段的话,还会涉及⽹关的转发、路由器的转发等等。
但是对于 ICMP 的头来讲,是没什么影响的。会影响的是根据⽬标 IP 地址,选择路由的下⼀跳,还有每经过⼀个路由器到达⼀个新的局域⽹,需要换 MAC 头⾥⾯的 MAC 地址。
说了这么多,可以看出 ping 这个程序是使⽤了 ICMP ⾥⾯的 ECHO REQUEST(类型为 8 ) 和 ECHO REPLY(类型为 0)。
- traceroute命令
traceroute充分利⽤ ICMP 差错报⽂类型;(在UNIX、MacOS中是这个命令,⽽在Windows中对等的命令叫做 tracert )。
- 使用
Windows:tracert + 域名或IP地址
Linux/macOS:traceroute + 域名或IP地址
① 定位从源主机到目标主机之间经过了哪些路由器,以及到达各个路由器的耗时
原理: traceroute使用UDP,主机之间通信,网络层IP数据报的首部中,有个TTL字段(Time To Live)。TTL的作用是,设置IP数据报被丢弃前,最多能够经过的节点数。
每经过一个中间节点,再向下一个节点转发数据前,都会将TTL减1。如果TTL不为0,则将数据报转发到下一个节点;否则,丢弃数据报,并返回错误,错误类型是时间超时。

问题:如何判断报文是否到达目标主机?
traceroute发送UDP报文时,将目标端口设置为较大的值( 33434 - 33464),避免目标主机B上该端口有在实际使用。
当报文到达目标主机B,目标主机B发现目标端口不存在,则向源主机A发送ICMP报文(Type=3,Code=3),表示目标端口不可达。
源主机A收到差错报文,发现Type=3,Code=3,知道已经到达目标主机B。记录下IP、耗费,检测结束。
② 故意设置不分⽚,从⽽确定路径的 MTU
有的时候我们并不知道路由器的 MTU ⼤⼩,以太⽹的数据链路上的 MTU 通常是 1500 字节,但是⾮以外⽹的 MTU 值就不⼀样了,所以我们要知道 MTU 的⼤⼩,从⽽控制发送的包⼤⼩。

它的⼯作原理如下:
⾸先在发送端主机发送 IP 数据报时,将 IP 包⾸部的分⽚禁⽌标志位设置为 1。根据这个标志位,途中的路由器不会对⼤数据包进⾏分⽚,⽽是将包丢弃。
随后,通过⼀个 ICMP 的不可达消息将数据链路上 MTU 的值⼀起给发送主机,不可达消息的类型为「需要进⾏分⽚但设置了不分⽚位」。发送主机端每次收到 ICMP 差错报⽂时就减少包的⼤⼩,以此来定位⼀个合适的 MTU 值,以便能到达⽬标主机。
相关文章:
第十八篇:一文说清楚ICMP的底层原理
作为程序员或者网络工程师,有时候无法访问对方主机;导致这个现象的有很多原因,那要排查具体的网络原因,可能会用到ping的指令。而ping的底层实现是互联⽹控制报⽂协议(ICMP)。 ICMP 全称是 Internet Contr…...
【优选算法】(第三十二篇)
目录 ⼆进制求和(easy) 题目解析 讲解算法原理 编写代码 字符串相乘(medium) 题目解析 讲解算法原理 编写代码 ⼆进制求和(easy) 题目解析 1.题目链接:. - 力扣(LeetCode&a…...
线程(四)线程的同步——条件变量
文章目录 线程线程的同步和互斥线程同步--条件变量什么是线程同步示例--条件变量的使用示例--使用两个线程对同一个文件进行读写示例--一个读者一个写者使用条件变量来实现同步 线程 线程的同步和互斥 线程同步–条件变量 是一个宏观概念,在微观上包含线程的相互…...
二维数组的旋转与翻转(C++)(上(这只是简单讲解))
二维数组的旋转与翻转(C) 引言 在计算机科学中,二维数组是一种常见的数据结构,广泛应用于图像处理、数据挖掘、机器学习等多个领域。二维数组的旋转与翻转是处理二维数据时经常需要用到的操作。本文将详细介绍二维数组的旋转与翻…...
【在Linux世界中追寻伟大的One Piece】System V共享内存
目录 1 -> System V共享内存 1.1 -> 共享内存数据结构 1.2 -> 共享内存函数 1.2.1 -> shmget函数 1.2.2 -> shmot函数 1.2.3 -> shmdt函数 1.2.4 -> shmctl函数 1.3 -> 实例代码 2 -> System V消息队列 3 -> System V信号量 1 -> Sy…...
【大数据】Spark弹性分布式数据集RDD详细说明
文章目录 整体介绍一、定义与特性二、操作与转换三、存储级别与持久化四、依赖关系与容错机制五、优化与性能调优 常见操作支持的数据格式1.文本文件 (Text Files)2. CSV 文件3. JSON 文件4. Parquet 文件5. Sequence Files6.Hadoop文件读取A. 读取HDFS上的文本文件B. 使用Hado…...
人参玉桂膏简介
一、产品基本信息 产品名称:人参玉桂膏 产品类别:植物饮料(专为特定体质设计) 配料:精选薏苡仁、荷叶、玉米须、赤小豆等纯然植物成分,辅以麦芽糖醇液、低聚果糖调节口感,陈皮、肉桂、人参&…...
消费者Rebalance机制
优质博文:IT-BLOG-CN 一、消费者Rebalance机制 在Apache Kafka中,消费者组 Consumer Group会在以下几种情况下发生重新平衡Rebalance: 【1】消费者加入或离开消费者组: 当一个新的消费者加入消费者组或一个现有的消费者离开消费…...
消息队列介绍
一、ActiveMQ 优点:性能单台(6000)成熟,已经在很多公司得到应用。各种协议支持好,有多个语言的成熟客户端 缺点:性能较弱,缺乏大规模吞吐的场景的应用,有江河日下之感 二、RabbitMQ…...
告别@Value,Spring Boot 3.3更优雅的配置注入方案
在Spring Boot的早期版本中,我们常使用Value注解来注入配置文件中的属性值。然而,这种方式虽然简单直接,却存在一些局限,比如它只能注入基本类型的值,并且需要显式地在每个需要注入的字段上使用注解。随着Spring Boot的…...
甲虫身体图像分割系统源码&数据集分享
甲虫身体图像分割系统源码&数据集分享 [yolov8-seg-EfficientRepBiPAN&yolov8-seg-C2f-FocusedLinearAttention等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challen…...
Qt - QMenu
QMenu 1、menu转string输出 //GlobalEnum.h #include <QObject> #include <QMetaEnum> class GlobalEnum : public QObject {Q_OBJECT public:EnumTest();enum Enum_Test{ZhangSan 0,WangWu,};Q_ENUM(Enum_Test) };#define EnumToString(e) \ QMetaEnum::fromTy…...
舵机驱动详解(模拟/数字 STM32)
目录 一、介绍 二、模块原理 1.舵机驱动原理 2.引脚描述 三、程序设计 main.c文件 servo.h文件 servo.c文件 四、实验效果 五、资料获取 项目分享 一、介绍 舵机(Servo)是在程序的控制下,在一定范围内连续改变输出轴角度并保持的电机系统。即舵机只支持…...
dvwa:文件包含、文件上传
文件包含 本地文件包含(敏感信息泄露)和远程文件包含(命令执行) 本地文件包含一般包含一些本地的敏感文件,如:/etc/passwd或/etc/shadow等 远程文件包含能使得服务器代码执行,如包含黑客vps的…...
基于 C# .NET Framework 4.0 开发实现 WCF 服务实例详解(二)——实现Windows服务内嵌WCF服务
目录 引言 1. 创建一个新的Windows服务项目 2. 添加WCF服务 2.1 添加服务接口和实现 2.2 添加服务配置 3. 实现Windows服务 3.1 修改Service1类 3.2 在项目中添加ServiceInstaller 4. 安装和运行Windows服务 4.1 编译项目 4.2 使用InstallUtil.exe安装服务 …...
【ArcGIS/C#】调用控制台处理代码
代码示例 private static string[] run_conda_process(string command, Action<string> on_msg, CancellationTokenSource cancel){if (string.IsNullOrEmpty(command)){return new string[]{null,ArcGIS.Desktop.Internal.Core.Conda.Resources.Error_Unexpected + &qu…...
06_23 种设计模式之《适配器模式》
文章目录 一、适配器模式基础知识实例 一、适配器模式基础知识 适配器模式定义:将一个类的接口转换成客户希望的另一个接 口。适配器模式使得原本由于接口不兼容而不能一起工作的那些类可 以一起工作。 Client:客户端,调用自已需要的领域接口…...
Go语言--快速入门
Go语言特点 我们先看一下简单的Go语言程序 package mainimport "fmt"func main() { // 错误,{ 不能在单独的行上fmt.Println("Hello, World!") }我们可以看到外型非常像我们的JAVA,但是不需要;作为结尾,…...
京东云主机怎么用?使用京东云服务器建网站(图文教程)
京东云主机怎么用?非常简单,本文京东云服务器网jdyfwq.com使用以使用京东云服务器搭建WordPress博客网站为例,来详细说下京东云主机的使用方法。使用京东云服务器快速搭建WordPress网站教程,3分钟基于应用镜像一键搞定,…...
Linux 基础入门操作-实验七 进程的介绍
实验七 进程的介绍 7.1 进程基础概念 Linux进程在内存中包含三部分数据:码段、堆栈段和数据段。代码段存放了程序的代码。代码段可以为机器中运行同一程序的数个进程共享。堆栈段存放的是子程序的返回地址、子程序的参数及程序的局部变量。而数据段则存放程序的全…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
idea大量爆红问题解决
问题描述 在学习和工作中,idea是程序员不可缺少的一个工具,但是突然在有些时候就会出现大量爆红的问题,发现无法跳转,无论是关机重启或者是替换root都无法解决 就是如上所展示的问题,但是程序依然可以启动。 问题解决…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
