前言
本文为 《图解系统》系列文章的个人学习笔记,对具体知识点与示例进行了归纳整理,详细内容参考小林coding 。
文章目录
一、OSI 七层网络模型与 TCP/IP 四层网络模型
1.1 OSI七层网络模型
OSI(Open System Interconnection)模型,即开放式系统互联,是国际标准化组织(ISO)制定的⼀个⽤于计算机或通信系统间互联的标准体系,旨在将计算机⽹络通信划分为七个不同的层级,每个层级都负责特定的功能。每个层级都构建在其下⽅的层级之上,并为上⽅的层级提供服务。七层从下到上分别是物理层、数据链路层、⽹络层、传输层、会话层、表示层和应⽤层。
1.2 TCP/IP四层网络模型
TCP/IP模型是⼀种⽤于组织和描述计算机⽹络通信的标准模型,它是互联⽹最常⽤的协议栈。TCP/IP 模型由两个主 要协议组成:TCP(Transmission Control Protocol)和 IP(Internet Protocol)。它是互联⽹通信的基础,也被 ⼴泛⽤于局域⽹和⼴域⽹等各种⽹络环境。 TCP/IP 模型分为四个层级,分别是网络接口层、网络层、传输层和应用层,每个层级负责特定的⽹络功能。
TCP/IP 网络模型相比 OSI 网络模型简化了不少,也更加易记,它们之间的关系如下图。
二、键入网址到网页显示,期间发生了什么?
2.1 HTTP——URL 解析 + HTTP 请求信息生成
在浏览器键入 URL 网址后,浏览器需要根据 URL 完成解析并生产对应HTTP 请求信息。
2.1.1 URL解析
首先浏览器做的第一步工作就是要对 URL 进行解析,从而生成发送给 Web 服务器的请求信息。URL 里的各个元素组成见下图,其中www.server.com
为服务器域名,/dir1/file1.html
为数据源文件的路径,所以 URL 实际上是请求服务器里的文件资源。
2.1.2 HTTP 请求信息生成
对 URL 进行解析之后,浏览器确定了 Web 服务器域名和文件名,接下来就是根据这些信息来生成 HTTP 请求消息(GET请求、POST请求等)。
2.2 DNS——域名解析
通过浏览器解析 URL 并生成 HTTP 消息后,需要委托操作系统将消息发送给 Web 服务器。但在发送 HTTP 消息前,还需要查询服务器域名对应的 IP 地址,因为委托操作系统发送消息时,必须提供通信对象的 IP 地址。有一种服务器就专门保存了 Web 服务器域名与 IP 的对应关系,它就是 DNS 服务器。
2.2.1 域名的层级关系
DNS 中的域名都是用句点来分隔的,比如 www.server.com
,这里的句点代表了不同层次之间的界限。在域名中,越靠右的位置表示其层级越高。
实际上域名最后还有一个点,比如www.server.com.
,这个最后的一个点代表根域名。也就是,.
根域是在最顶层,它的下一层就是 .com
顶级域,再下面是 server.com
。所以域名的层级关系类似一个树状结构:
2.2.2 域名解析流程
1. 客户端首先会发出一个 DNS 请求,问 www.server.com 的 IP 是啥,并发给本地 DNS 服务器(也就是客户端的 TCP/IP 设置中填写的 DNS 服务器地址)。
2. 并发给本地 DNS 服务器(也就是客户端的 TCP/IP 设置中填写的 DNS 服务器地址)。如果没有,本地 DNS 会去问它的根域名服务器,根域名服务器是最高层次的,它不直接用于域名解析,但能指明一条道路。
3. 根 DNS 收到来自本地 DNS 的请求后,发现后置是 .com,指示本地 DNS 服务器访问 .com 顶级域名服务器。
4. 本地 DNS 收到 .com 顶级域名服务器的地址后,发起请求。
5. .com 顶级域名服务器指示本地 DNS 访问 www.server.com 权威 DNS 服务器。
6. 本地 DNS 于是进一步访问权威 DNS 服务器。
7. 权威 DNS 服务器查询后将对应的 IP 地址 X.X.X.X 告诉本地 DNS。
8. 本地 DNS 再将 IP 地址返回客户端,客户端和目标建立连接。
至此可以发现,除了权威 DNS 服务器,其他 DNS 服务器都不直接用于域名解析,只指路不带路。
2.3 协议栈——系统接口
通过 DNS 获取到 IP 后,就可以把 HTTP 的传输工作交给操作系统中的协议栈。应用程序(浏览器)通过调用 Socket 库,来委托协议栈工作。协议栈的上半部分有两块,分别是负责收发数据的 TCP 和 UDP 协议,协议栈的下面一半是用 IP 协议控制网络包收发操作。
2.4 TCP——可靠传输
HTTP 是基于 TCP 协议传输的,在此简要介绍 TCP 协议。
2.4.1 TCP 包头格式
首先,源端口号和目标端口号是不可少的,基于此数据就知道应该发给哪个应用。
其次,是包的序号,这个是为了解决包乱序的问题。
此外,还有确认号,用于确认正确接收的数据。
接下来还有一些状态位。例如 SYN
是发起一个连接,ACK
是回复,RST
是重新连接,FIN
是结束连接等。
还有一个重要的就是窗口大小。TCP 要做流量控制,通信双方各声明一个窗口(缓存大小)。
2.4.2 TCP 三次握手建立连接
在 HTTP 传输数据之前,首先需要 TCP 建立连接,TCP 连接的建立,通常称为三次握手。三次握手过程中双方都完成了一次收发,目的是保证双方都有发送和接收的能力。
2.4.3 TCP 分割数据与报文生成
如果 HTTP 请求消息比较长,超过了 MSS
的长度,这时 TCP 就需要把 HTTP 的数据拆解成一块块的数据发送。
MTU
:一个网络包的最大长度,以太网中一般为1500
字节。MSS
:除去 IP 和 TCP 头部之后,一个网络包所能容纳的 TCP 数据的最大长度。
在双方建立了 TCP 连接后,TCP 报文中的数据部分就是存放 HTTP 头部 + 数据,组装好 TCP 报文之后,就需交给下面的网络层处理。至此,网络包的报文如下图。
2.5 IP——远程定位
TCP 模块在执行连接、收发、断开等各阶段操作时,都需要委托 IP 模块将数据封装成网络包发送给通信对象。
2.5.1 IP 包头格式
在 IP 协议里面需要有源地址 IP 和 目标地址 IP,其中源地址 IP 是客户端输出的 IP 地址,目标地址是通过 DNS 域名解析得到的 Web 服务器 IP。
HTTP 是经过 TCP 传输的,所以在 IP 包头的协议号要填写为 06(十六进制),表示协议为 TCP。
2.5.2 源 IP 地址选择
当存在多个网卡时,在填写源地址 IP 时,就需要判断到底应该填写哪个地址。这个时候就需要根据路由表规则,来判断在当前目的 IP 地址下,该选择哪一个网卡作为源地址 IP。
2.5.3 IP 报文生成
2.6 MAC——两点传输
2.6.1 MAC 包头格式
MAC 头部是以太网使用的头部,需要发送方 MAC 地址和接收方目标 MAC 地址,用于两点之间的传输。
一般在 TCP/IP 通信里,MAC 包头的协议类型只使用:
0800
: IP 协议0806
: ARP 协议
2.6.2 对方 MAC 地址获取——ARP 协议
ARP
协议可以帮我们找到对方的 MAC 地址:ARP 协议会在以太网中以广播的形式,对以太网所有的设备喊出:“这个 IP 地址是谁的?请把你的 MAC 地址告诉我”。
如果对方和自己处于同一个子网中,那么通过上面的操作就可以得到对方的 MAC 地址。那如果对方和自己不在同一个子网呢?
要解答这个问题,首先要明确这个“对方”是谁?在 IP 包生成后,IP 包头中的目的 IP 地址即为 Web服务器 IP,显然 Web 服务器与当前客户端不在同一子网,那么在 MAC 包处理过程的“对方”是谁呢?这个“对方”是根据 目的 IP + 路由表 确定下来的下一跳地址。通常来说,这个下一跳地址即为路由器地址,也就是说,ARP
协议根据 IP 地址获取的 MAC地址,都是 路由器的 IP/MAC 地址,而不是 Web服务器 IP/MAC 地址。
因此,MAC 针对的是两点传输,而非 IP 的远程定位与路由。可以认为,IP 的路由确定了每一跳的 MAC 两点传输的双方。
2.6.3 MAC 报文生成
2.7 网卡、交换机、路由器——发送与转发
2.7.1 网卡
网络包只是存放在内存中的一串二进制数字信息,没有办法直接发送给对方。因此,我们需要将数字信息转换为电信号,才能在网线上传输,也就是说,这才是真正的数据发送过程。负责执行这一操作的是网卡,要控制网卡还需要靠网卡驱动程序。
网卡驱动获取网络包之后,会将其复制到网卡内的缓存区中,接着会在其开头加上报头和起始帧分界符,在末尾加上用于检测错误的帧校验序列。
2.7.2 交换机
交换机的设计是将网络包原样转发到目的地。交换机工作在 MAC 层,也称为二层网络设备。
计算机的网卡本身具有 MAC 地址,并通过核对收到的包的接收方 MAC 地址判断是不是发给自己的。相对地,交换机的端口不核对接收方 MAC 地址,而是直接接收所有的包并存放到缓冲区中。因此,和网卡不同,交换机的端口不具有 MAC 地址。
将包存入缓冲区后,接下来需要查询一下这个包的接收方 MAC 地址是否已经在 MAC 地址表中有记录了。
交换机的 MAC 地址表主要包含两个信息:一个是设备的 MAC 地址,另一个是该设备连接在交换机的哪个端口上。所以,交换机根据 MAC 地址表查找 MAC 地址,然后将信号发送到相应的端口。如果地址表中找不到指定的 MAC 地址,交换机会将包转发到除了源端口之外的所有端口上。
2.7.3 路由器
路由器是基于 IP 设计的,俗称三层网络设备,路由器的各个端口都具有 MAC 地址和 IP 地址。(交换机是基于以太网设计,俗称二层网络设备,交换机的端口不具有 MAC 地址)
路由器的端口具有 MAC 地址,因此它就能够成为以太网的发送方和接收方;同时还具有 IP 地址,从这个意义上来说,它和计算机的网卡是一样的。
当转发包时,首先路由器端口会接收发给自己的以太网包(即检查目标 MAC 地址和自身是否匹配),然后路由表查询转发目标,再由相应的端口作为发送方将以太网包发送出去。
2.8 小结
- 基于URL解析,完成HTTP请求报文生成;
- 基于DNS解析,确定四元组(源IP/端口、目的IP/端口),调用socket接口进行协议栈处理;
- TCP报文封装;
- IP报文封装;
- 基于路由表和ARP协议,确定目的MAC地址,完成MAC报文/以太网包封装;
TIP1:网络接口层的传输单位是帧(frame),IP 层的传输单位是包(packet),TCP 层的输单位是段(segment),HTTP 的传输单位则是消息或报文(message)。
TIP2:在网络包传输的过程中,源 IP 和目标 IP 始终是不会变的,一直变化的是 MAC 地址,因为需要 MAC 地址在以太网内进行两个设备之间的包传输。
三、TCP 面试题
3.1 序号 & 确认应答号计算
首先回答什么 TCP 包头中的序号、确认应答号的含义与其对应的重要概念:
- 序号
- 序号的含义 :TCP 是面向字节流的,每一个字节数据都对应了一个序号,用来解决网络包乱序问题。
- 初始序号:当新连接建立的时候,第一个字节数据的序号称为 ISN(Initial Sequence Number),即初始序号。在建立连接时由计算机生成的随机数作为其初始值,通过 SYN 包传给接收端主机。
- 报文段序号:TCP 包数据中第一个字节数据对应的序号。如果一个 TCP 报文段的序号为 301,且它携带了 100 字节的数据,就表示这 100 个字节的数据的字节序号范围是 [301, 400],该报文段携带的第一个字节序号是 301,最后一个字节序号是 400。
- 确认号
- 确认号的含义:TCP 是可靠传输,接收端在收到字节流后需要应答确认数据已经正确接收。确认号指定了接收方下一次期望收到的字节数据序号,发送端可以认为确认号以前的字节数据都已经被正常接收。比如发送方发送了一个报文段序号为 301 的 TCP 段,这个段携带了 100 字节数据,则接收方应当回复的确认号是 401,它表示接收方已经收到了字节序号为 [0, 400] 的数据,现在期望你发送字节序号为 401 以及以后的数据。
- 累计确认:在 TCP 协议中,一般采用累积确认的方式,即每传送多个连续 TCP 段,可以只对最后一个 TCP 段进行确认。这种方法提高了传输效率,减少了传输开销。
- ACK标志位:只有当 ACK 标志位被置位的时候,确认号这个字段才有效。
参考资料:一文搞懂TCP连接中的序号seq和确认应答号ack
3.2 TCP 重传机制
TCP 实现可靠传输的方式之一,是通过序号与确认应答。在错综复杂的网络,会出现数据在传输过程中丢失的情况,所以 TCP 针对数据包丢失的情况,会用重传机制解决。TCP 常见的重传机制包括:
- 超时重传:基于定时器的重传机制。
- 快速重传:基于数据的重传机制,解决了重传时延长的问题。
- SACK:「接收方」对接收字节流数据进行选择性确认,减少未丢失数据的重复发送(ACK < SACK)。
- D-SACK:「接收方」使用了 SACK 告诉「发送方」有哪些数据被重复接收了(ACK > SACK)。
3.2.1 超时重传
工作机制:「发送方」在发送数据时设定一个定时器,当超过指定时间后没有收到对方的
ACK
确认应答报文,就会重发该数据。
a. 触发场景
在以下两种情况发生超时重传:
1)数据包丢失
2)确认应答丢失
b. 定时器取值
「针对首次超时重传」
超时重传时间是以 RTO
(Retransmission Timeout 超时重传时间)表示。假设在重传的情况下,超时时间 RTO
「较长或较短」时,会发生什么事情呢?
- 当超时时间 RTO 较大时,重发就慢,丢了老半天才重发,没有效率,性能差;
- 当超时时间 RTO 较小时,会导致可能并没有丢就重发,于是重发的就快,会增加网络拥塞,导致更多的超时,更多的超时导致更多的重发。
根据上述的两种情况,我们可以得知,超时重传时间 RTO
的值应该略大于报文往返 RTT
的值。然而,实际上「报文往返 RTT
的值」是经常变化的,因为我们的网络也是时常变化的,所以「超时重传时间 RTO
的值」应该是一个动态变化的值。
Linux 通过采样 RTT 的时间和 RTT 的波动范围,通过加权平均算出一个平滑 RTT 的值,具体计算公式参考了 RFC6289
标准。
「针对多次超时重传」
如果超时重发的数据,再次超时的时候,又需要重传的时候,TCP 的策略是超时间隔加倍。也就是每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍。两次超时,就说明网络环境差,不宜频繁反复发送。
c. 超时重传机制缺陷
超时触发重传存在的问题是,超时周期可能相对较长。于是就可以用「快速重传」机制来解决超时重发的时间等待。
3.2.2 快速重传
工作机制:当收到三个相同的
ACK
报文时,会在定时器过期之前,重传丢失的报文段。
TCP 还有另外一种快速重传(Fast Retransmit)机制,它不以时间为驱动,而是以数据驱动重传。
快速重传机制只解决了一个问题,就是超时时间的问题,但是它依然面临着另外一个问题:重传的时候,是重传一个,还是重传所有的问题。下图展现了这个问题,Seq 3、4、5均已经正确接收,但在现有的 ACK
累计重传机制下,都只能在此重新发送Seq 3、4、5。为解决这一问题,引入了 SACK
机制。
3.2.3 SACK的引入
工作机制:
SACK
将已收到的数据的信息发送给「发送方」,这样发送方就可以知道哪些数据收到了,哪些数据没收到,知道了这些信息,就可以只重传丢失的数据。
SACK( Selective Acknowledgment)即为选择性确认,「接收方」需要在 TCP 头部「选项」字段里加一个 SACK
的东西,将已收到的数据的信息发送给「发送方」。
如下图,发送方收到了三次同样的 ACK 确认报文,于是就会触发快速重发机制,通过 SACK
信息发现只有 200~299
这段数据丢失,则重发时,就只选择了这个 TCP 段进行重复发送。
TIP:可以注意到,SACK > ACK
时,选择性地指示了接收方已经成功接收的数据。
3.2.4 D-SACK的引入
工作机制:通过
SACK
将重复接收数据的信息发送给「发送方」。
Duplicate SACK 又称 D-SACK,其主要使用了 SACK 来告诉「发送方」有哪些数据被重复接收了,此时 SACK < ACK
。
以 ACK 丢包为例,简要阐述 D-SACK 的工作。
3.3 TCP 和 UDP 可以使用同一个端口吗?
先说答案,是可以的。
TCP/UDP 各自的端口号是相互独立的,两个协议都有自己的端口号空间,如 TCP 有一个 80 号端口,UDP 也可以有一个 80 号端口,二者并不冲突。这是因为TCP和UDP是两个完全不同的协议,它们工作在传输层,各自维护不同的连接和会话。TCP 和 UDP 在内核中是两个完全独立的软件模块,因此两者的数据流是完全独立的。
但在实际应用中,为了避免潜在的冲突和混淆,通常建议为不同的协议分配不同的端口号。这样可以提高系统的可维护性和可管理性。
四、IP 面试题
4.1 IP 地址分类
IP 地址分类成了 5 种类型,分别是 A 类、B 类、C 类、D 类、E 类。下图中黄色部分为分类号,用以区分 IP 地址类别。
4.1.1 A、B、C 类 IP 地址
对于 A、B、C 类主要分为两个部分,分别是网络号和主机号。
A、B、C 分类地址最大主机个数是如何计算的呢?
最大主机个数,就是要看主机号的位数。例如,C 类地址的主机号占 8 位,那么 C 类地址的最大主机个数:
2
8
−
2
=
254
2^8-2=254
28−2=254
其中,减 2 的原因是,在 IP 地址中有两个 IP 是特殊的,分别是主机号全为 1 和 全为 0 地址:
1)主机号全为 1 指定某个网络下的所有主机,用于广播;
2)主机号全为 0 指定某个网络;
4.1.2 D、E 类 IP 地址
D 类和 E 类地址是没有主机号的,所以不可用于主机 IP,D 类常被用于多播,E 类是预留的分类,暂时未使用。
多播地址用于什么?
多播用于将包发送给特定组内的所有主机。
由于广播无法穿透路由,若想给其他网段发送同样的包,就可以使用可以穿透路由的多播。
TIP:组播地址不是用于机器ip地址的,因为组播地址没有网络号和主机号,所以跟dhcp没关系。组播地址一般是用于udp协议,机器发送UDP组播数据时,目标地址填的是组播地址,那么在组播组内的机器都能收到数据包。是否加入组播组和离开组播组,是由socket一个接口实现的,主机ip是不用改变的。
4.1.3 IP 地址分类的优缺点
IP分类的优点
分类地址的优点是简单明了、选路(基于网络地址)简单。
不管是路由器还是主机解析到一个 IP 地址时候,我们判断其 IP 地址的首位是否为 0,为 0 则为 A 类地址,那么就能很快的找出网络地址和主机地址。其余分类判断方式参考如下图:
IP分类的缺点
(1)同一网络下没有地址层次,比如一个公司里用了 B 类地址,但是可能需要根据生产环境、测试环境、开发环境来划分地址层次,而这种 IP 分类是没有地址层次划分的功能,所以这就缺少地址的灵活性。
(2)A、B、C类有个尴尬处境,就是不能很好的与现实网络匹配。C 类地址能包含的最大主机数量实在太少, B 类地址能包含的最大主机数量又太多。
4.2 IP 协议相关技术
4.2.1 DNS
通过DNS 域名解析,可以将域名网址自动转换为具体的 IP 地址。
4.2.2 ARP
ARP 协议可以基于「路由表」确定的 IP 数据包下一跳,求得下一跳的 MAC 地址。
那么 ARP 又是如何知道对方 MAC 地址的呢?
ARP 是借助 ARP 请求与 ARP 响应两种类型的包确定 MAC 地址的。
- 主机会通过广播发送 ARP 请求,这个包中包含了想要知道的 MAC 地址的主机 IP 地址。
- 当同个链路中的所有设备收到 ARP 请求时,会去拆开 ARP 请求包里的内容,如果 ARP 请求包中的目标 IP 地址与自己的 IP 地址一致,那么这个设备就将自己的 MAC 地址塞入 ARP 响应包返回给主机。
RARP 协议是什么?
ARP 协议是已知 IP 地址求 MAC 地址,RARP 协议正好相反,它是已知 MAC 地址求 IP 地址。例如将打印机服务器等小型嵌入式设备接入到网络时就经常会用得到。
4.2.3 DHCP
我们的电脑通常都是通过 DHCP 动态获取 IP 地址,大大省去了配 IP 信息繁琐的过程。
我们的电脑是如何通过 DHCP 动态获取 IP 地址的?
- 客户端首先发起 **DHCP 发现报文(DHCP DISCOVER)**的 IP 数据报,由于客户端没有 IP 地址,也不知道 DHCP 服务器的地址,所以使用的是 UDP 广播通信,其使用的广播目的地址是 255.255.255.255(端口 67)并且使用 0.0.0.0(端口 68) 作为源 IP 地址。DHCP 客户端将该 IP 数据报传递给链路层,链路层然后将帧广播到所有的网络中设备。
- DHCP 服务器收到 DHCP 发现报文时,用 DHCP 提供报文(DHCP OFFER) 向客户端做出响应。该报文仍然使用 IP 广播地址 255.255.255.255,该报文信息携带服务器提供可租约的 IP 地址、子网掩码、默认网关、DNS 服务器以及 IP 地址租用期。
- 客户端收到一个或多个服务器的 DHCP 提供报文后,从中选择一个服务器,并向选中的服务器发送**DHCP 请求报文(DHCP REQUEST)**进行响应,回显配置的参数。
- 最后,服务端用 DHCP ACK 报文对 DHCP 请求报文进行响应,应答所要求的参数。
一旦客户端收到 DHCP ACK 后,交互便完成了,并且客户端能够在租用期内使用 DHCP 服务器分配的 IP 地址。如果租约的 DHCP IP 地址快期后,客户端会向服务器发送 DHCP 请求报文:
- 服务器如果同意继续租用,则用 DHCP ACK 报文进行应答,客户端就会延长租期。
- 服务器如果不同意继续租用,则用 DHCP NACK 报文,客户端就要停止使用租约的 IP 地址。
可以发现,DHCP 交互中,全程都是使用 UDP 广播通信。
4.2.4 NAT
为缓解IPv4 的地址紧缺问题,提出了一种网络地址转换 NAT 的方法。
简单的来说 NAT 就是同个公司、家庭、教室内的主机对外部通信时,把源 IP 地址中的私有 IP 地址转换成公有 IP 地址。
若有 N 个私有 IP 地址,难道就要求有 N 个公有 IP 地址?
对于普通的 NAT 转换,N 个私有 IP 地址就要求有 N 个公有 IP 地址,显然这无法缓解 IPv4 地址耗尽的问题。
因此,针对绝大多数的网络应用都是使用 TCP 或 UDP 传输层协议来传输数据的现状,可以将**「 IP 地址 + 端口号」一起进行转换。这样对于N 个私有 IP 地址,就只需要使用一个公有 IP 地址 + N 个端口(或更多端口)就可以了,这种转换技术就叫网络地址与端口转换NAPT**。
图中有两个客户端 192.168.1.10 和 192.168.1.11 同时与服务器 183.232.231.172 进行通信,并且这两个客户端的本地端口都是 1025。
此时,两个私有 IP 地址都转换 IP 地址为公有地址 120.229.175.121,但是以不同的端口号作为区分。于是,生成一个 NAPT 路由器的转换表,就可以正确地转换地址跟端口的组合,令客户端 A、B 能同时与服务器之间进行通信。这种转换表在 NAT 路由器上自动生成。
NAT 技术有什么缺点?
由于 NAT/NAPT 都依赖于自己的转换表,因此会有以下的问题:
(1)转换表的生成与转换操作都会产生性能开销。
(2)外部无法主动与 NAT 内部服务器建立连接,因为 NAPT 转换表没有转换记录。
(3)通信过程中,如果 NAT 路由器重启了,所有的 TCP 连接都将被重置。
如何解决 NAT 潜在的问题呢?
(1)改用 IPv6:IPv6 可用范围非常大,以至于每台设备都可以配置一个公有 IP 地址。
(2)NAT 穿透技术:客户端主动从 NAT 设备获取公有 IP 地址,然后自己建立端口映射条目,然后用这个条目对外通信,就不需要 NAT 设备来进行转换了。
4.2.5 ICMP
ICMP 全称是 Internet Control Message Protocol,也就是互联网控制报文协议。
ICMP 功能都有啥?
ICMP 主要的功能包括:确认 IP 包是否成功送达目标地址、报告发送过程中 IP 包被废弃的原因和改善网络设置等。
在 IP 通信中如果某个 IP 包因为某种原因未能达到目标地址,那么这个具体的原因将由 ICMP 负责通知源服务器。
如上图例子,主机 A
向主机 B
发送了数据包,由于某种原因,途中的路由器 2
未能发现主机 B
的存在,这时,路由器 2
就会向主机 A
发送一个 ICMP目标不可达数据包,说明发往主机 B
的包未能成功。
ICMP 包头格式
ICMP 报文是封装在 IP 包里面,它工作在网络层,是 IP 协议的助手。
ICMP 类型
ICMP 大致可以分为两大类:
- 一类是用于诊断的查询消息,也就是**「查询报文类型」**
- 另一类是通知出错原因的错误消息,也就是**「差错报文类型」**
4.3 Ping 的工作原理
ping 是基于 ICMP 协议工作的。正如4.2.5小节所描述,ICMP 大致可以分为两大类:
- 一类是用于诊断的查询消息,也就是**「查询报文类型」**
- 另一类是通知出错原因的错误消息,也就是**「差错报文类型」**
4.3.1 ping——查询报文类型的使用
回送消息 —— 类型
0
和8
回送消息用于进行通信的主机或路由器之间,判断所发送的数据包是否已经成功到达对端的一种消息,ping
命令就是利用这个消息实现的。
可以向对端主机发送回送请求的消息(ICMP Echo Request Message,类型 8),可以向对端主机发送回送请求的消息(ICMP Echo Request Message,类型 8)。
4.3.2 traceroute——差错报文类型的使用
有一款充分利用 ICMP 差错报文类型的应用叫做 traceroute
。
4.3.2.1 路径追踪
traceroute 的第一个作用就是故意设置特殊的 TTL,来追踪去往目的地时沿途经过的路由器。
traceroute 的参数指向某个目的 IP 地址:
traceroute 192.168.1.100
这个作用是如何工作的呢?
它的原理就是利用 IP 包的生存期限 从 1开始按照顺序递增的同时发送 UDP 包,!强制接收 ICMP 超时消息的一种方法。
比如,将 TTL 设置 为 1,则遇到第一个路由器,就牺牲了,接着返回 ICMP 差错报文网络包,类型是时间超时。
接下来将 TTL 设置为 2 ,第一个路由器过了,遇到第二个路由器也牺牲了,也同时返回了ICMP 差错报文数据包,如此往复,直到到达目的主机。这样的过程,traceroute 就可以拿到了所有的路由器 IP。
当然有的路由器根本就不会返回这个 ICMP,所以对于有的公网地址,是看不到中间经过的路由的。
发送方如何知道发出的 UDP 包是否到达了目的主机呢?
traceroute 在发送 UDP 包时,会填入一个不可能的端口号值作为 UDP 目标端口号:33434。
然后对于每个下一个探针,它都会增加一个,这些端口都是通常认为不会被使用,不过,没有人知道当某些应用程序监听此类端口时会发生什么。
当目的主机,收到 UDP 包后,会返回 ICMP 差错报文消息,但这个差错报文消息的类型是「端口不可达]。所以,当差错报文类型是端口不可达时,说明发送方发出的 UDP 包到达了目的主机。
4.3.2.2 路径MTU发现
traceroute 还有一个作用是故意设置不分片,从而确定路径的 MTU。
这么做是为了什么?
这样做的目的是为了路径MTU发现。因为有的时候我们并不知道路由器的 MTU 大小,以太网的数据链路上的 MTU 通常是 1500 字节,但是非以太网的 MTU 值就不一样了,所以我们要知道 MTU 的大小,从而控制发送的包大小。
这个作用的工作原理是?
首先在发送端主机发送 IP 数据报时,将 IP包首部的分片禁止标志位设置为1。
根据这个标志位,途中的路由器不会对大数据包进行分片,而是将包丢弃。随后,通过一个 ICMP 的不可达消息将数据链路上 MTU 的值一起给发送主机,不可达消息的类型为「需要进行分片但设置了不分片位」。
发送主机端每次收到 ICMP 差错报文时就减少包的大小,以此来定位一个合适的 MTU 值,以便能到达目标主机。