【Linux】第15期 讲解IP网络层核心原理与机制

目录

  • 开头
  • 一.IP协议
    • 1.协议格式
      • [(1)第一行:版本 + 首部长度 + 服务类型 + 总长度](#(1)第一行:版本 + 首部长度 + 服务类型 + 总长度)
        • a.4位版本(version)
        • [b.4 位 首部长度(IHL, Internet Header Length)](#b.4 位 首部长度(IHL, Internet Header Length))
        • [c.8 位 服务类型(TOS, Type Of Service)](#c.8 位 服务类型(TOS, Type Of Service))
        • d.16位总长度
      • (2)第二行:16位标识+3位标志+13位片偏移
        • [a.16 位标识](#a.16 位标识)
        • [b.3 位标志](#b.3 位标志)
        • [c.13 位片偏移](#c.13 位片偏移)
      • [(3)第三行:TTL + 协议 + 首部校验和](#(3)第三行:TTL + 协议 + 首部校验和)
        • [a.8 位 生存时间(TTL, Time To Live)](#a.8 位 生存时间(TTL, Time To Live))
        • [b.8 位 协议(Protocol)](#b.8 位 协议(Protocol))
        • [c.16 位 首部校验和(Header Checksum)](#c.16 位 首部校验和(Header Checksum))
      • [(4)第四、五行:32 位 源 IP 地址、32 位 目的 IP 地址](#(4)第四、五行:32 位 源 IP 地址、32 位 目的 IP 地址)
    • 2.网段划分
      • [(1)第一代方案:有类地址(A/B/C/D/E 五类)](#(1)第一代方案:有类地址(A/B/C/D/E 五类))
      • [(2)第二代方案:CIDR 无类域间路由 + 子网掩码](#(2)第二代方案:CIDR 无类域间路由 + 子网掩码)
    • 3.公网和子网
    • 4.路由
  • 结尾
  • 往期回顾

开头

Ok了,上一期我们学习了传输层UDP、TCP,今天这一期我们继续从上到下的讲解------网络层,废话不多说,我们直接开始

网络层是 TCP/IP 协议栈的核心分层之一,承担着跨网络端到端通信的核心职责,解决了 "数据从全球任意一个节点出发,如何找到路径到达另一个节点" 的根本问题

一句话定位:网络层解决的是「数据包怎么从一个国家/一个城市 / 一个网段,送到另一个国家/另一个城市 / 另一个网段」的问题,是整个互联网的 "路由导航系统"

一.IP协议

1.协议格式

如上图,是IPv4数据报首部格式,采用**网络字节序(大端模式)**排列,横向以bit为单位,共有4字节

  • 固定基础首部 :前 5 行,共 20 字节,所有 IP 报文必带;
  • 选项:可变长,最多 40 字节;
  • IP 首部总长度范围:20 ~ 60 字节,必须是 4 字节的整数倍

(1)第一行:版本 + 首部长度 + 服务类型 + 总长度

a.4位版本(version)
  • 作用:标识 IP 协议的版本
  • 取值 :固定为 4,代表 IPv4;如果是 IPv6 则值为 6。
  • 接收方首先读取该字段,判断用哪个版本的协议栈解析报文。

b.4 位 首部长度(IHL, Internet Header Length)
  • 核心规则 :计数单位是 4 字节(32 位字) ,不是 1 字节。
    计算公式:IP首部总字节数 = 首部长度数值 × 4
  • 取值范围
    • 最小值 5 → 5×4 = 20 字节(无任何选项的标准首部)
    • 最大值 15 → 15×4 = 60 字节(选项占满的最大首部)
  • 存在意义:因为 IP 首部有可变长的「选项」字段,总长度不固定,接收方必须靠这个字段才能准确找到「首部结束、数据开始」的边界
c.8 位 服务类型(TOS, Type Of Service)
  • 原始设计:用来标记数据包的服务质量要求,分为 3 位优先级、1 位最小延迟、1 位最大吞吐量、1 位可靠性、1位最小成本、1 位保留。
  • 现代演进 :现在基本演变为 DSCP(差分服务代码点),前 6 位用来区分业务等级,给语音、视频、游戏等低延迟业务分配更高的转发优先级,实现网络 QoS。
  • 普通数据报文该字段通常为 0
d.16位总长度
  • 单位:字节
  • 含义整个 IP 数据报的总长度 = IP 首部长度 + 数据载荷长度
  • 取值范围:0 ~ 65535 字节,理论最大约 64KB。
  • 接收方靠这个字段,结合首部长度,就能算出数据部分的长度:数据长度 = 总长度 - 首部长度

看到这里,同学们一定有疑问:为什么TCP报头只需要IHL就能实现报头与数据的分离,但是IP协议报头却需要多加一个16位总长度呢???

原因是:数据链路层向上交给网络层的是一串连续的字节流,如果只有IHL,我们只知道IP头部有多少字节,并不知道数据是从哪里截止的。但是TCP报文是由IP协议完整交付给传输层的,也就是说,IP已经把一整个完整的TCP报文交给了传输层,只需要通过IHL确定有效载荷的起始位置,剩下的全部字节就是TCP的有效载荷

(2)第二行:16位标识+3位标志+13位片偏移

这一行是什么东西??作用是什么??

不急,讲解IP协议报头第二行结构前,我们要先来学习一下IP的分片与重组

我们要先知道数据链路层的一个概念------MTU

MTU(Maximum Transmission Unit,最大传输单元)是数据链路层的核心属性:每一种链路技术(以太网、WiFi、PPP 等)都有自己能承载的最大 IP 数据报长度,最常见的以太网 MTU 就是 1500 字节。如果 IP 数据报总长度超过了当前链路的 MTU,数据链路层就无法把它封装成帧发送出去

直白点说就是:我能单次传输的数据量最大是 1500 (MTU),你给我的报文如果超过这个长度,你要自行分片和组装哦

但是分片会有很多的缺点:

IP 层本身没有重传机制,只要任意一个分片丢失,整个原始 IP 报文就彻底作废

也就是说,一份数据被IP网络层分成了多片发送,如果在传输过程中,只丢了其中一份,就要重新发送一整份数据

分片越多,重传浪费越严重。更糟糕的是,TCP 根本不知道是 IP 分片丢了,它只会感知到「这个段没收到确认」,然后重传整个段,进而又会产生一批新的分片,形成恶性循环


为了解决分片带来的资源浪费,我们就需要对传输层 下手

我们在上一期学习传输层TCP协议滑动窗口机制的时候,有没有想过:为什么要把窗口内的数据划分成一段一段的发送,怎么不把窗口中的所有数据一起发出去??------其实就是因为有MTU 的限制

TCP 在三次握手建立连接时,会互相协商 MSS(Maximum Segment Size,最大分段大小),它的定义非常直白:

复制代码
 **MSS = 链路 MTU - IP 首部长度 - TCP 首部长度**

以最常见的以太网 MTU=1500 字节为例:

  • IP 首部固定 20 字节,TCP 首部固定 20 字节
  • MSS = 1500 - 20 - 20 = 1460 字节

TCP把要发送的数据大小限制在1460字节内,这样发送的总报文大小就不会超过MTU,IP层就不需要分片,直接交给数据链路层就能直接发送


a.16 位标识

相当于原始报文的身份证号

当一个 IP 数据报被分片后,同一个原始报文的所有分片,标识字段的值完全相同。接收端的 IP 层正是依靠这个字段,把散落的分片归类到同一个 "分组" 里,为后续重组做准备


b.3 位标志

三个比特是分片的控制开关,从高位到低位分别是:

  • 第 1 位:保留位:预留未使用,协议规定必须置为 0,为未来扩展留空间。
  • 第 2 位:DF 位(Don't Fragment,禁止分片)
    • 置 1:禁止对该报文分片。如果报文长度超过链路 MTU,路由器会直接丢弃报文,并向源主机返回 ICMP 差错报文。路径 MTU 发现(PMTUD)技术就是靠这个位实现的。
    • 置 0:允许路由器在必要时对报文分片。
  • 第 3 位:MF 位(More Fragments,更多分片)
    • 置 1:表示当前分片不是最后一个,后面还有更多分片
    • 置 0:表示这是整个原始报文的最后一个分片
    • 特殊情况:未被分片的完整报文,MF 位也置 0

c.13 位片偏移

相当于每个分片的位置坐标 ,标记当前分片的数据部分,在原始 IP 报文的数据区中的起始位置。

  • 单位特殊:字段数值的单位不是字节,而是8 字节。实际偏移字节数 = 片偏移字段值 × 8。
  • 设计原因:13 位二进制最多表示 8192 个数值,以 8 字节为单位就能覆盖 8192×8=65536 字节,刚好匹配 IP 数据报最大 65535 字节的长度范围。
  • 长度规则:除最后一个分片外,前面所有分片的数据长度必须是 8 字节的整数倍,保证下一个分片的偏移值是整数,所有分片数据首尾衔接、不重叠、不空缺

(3)第三行:TTL + 协议 + 首部校验和

a.8 位 生存时间(TTL, Time To Live)
  • 核心作用:限制数据包经过路由器的最大跳数,防止IP数据包在网络里无限环路转发
  • 工作规则:数据包每经过一台路由器,TTL 值减 1;当 TTL 减到 0 时,路由器直接丢弃该数据包,并向源主机返回 ICMP "时间超时" 差错报文。
  • 常见默认值:Linux 系统默认 64,Windows 系统默认 128,网络设备通常默认 255

b.8 位 协议(Protocol)
  • 位置:第 72~79 比特
  • 作用 :指示 IP 数据报的数据部分,承载的是哪一种上层协议,接收方靠它把数据交给对应的内核模块处理。
  • 经典取值

c.16 位 首部校验和(Header Checksum)
  • 校验范围只校验 IP 首部本身,不校验数据部分
  • 算法:16 位二进制反码求和,和 TCP 校验和算法一致。
  • 特点 :数据包每经过一个路由器,TTL 都会减 1,首部内容变化,因此每一跳都要重新计算首部校验和
  • 校验失败的数据包会被直接丢弃,不通知发送方

(4)第四、五行:32 位 源 IP 地址、32 位 目的 IP 地址

源 IP 地址:发送该 IP 数据报的源主机的 IPv4 地址

目的 IP 地址:该 IP 数据报要送达的目标主机的 IPv4 地址

2.网段划分

IP 地址是 32 位的二进制地址,标识网络中的每一台主机。但如果 32 位全用来唯一标识主机,路由器就需要记住全球每一台主机的地址,路由表会无限膨胀,转发效率极低

IP 协议把 32 位地址拆成了两部分,这就是网段划分的核心逻辑

  • 网络号:标识一个独立的网段 / 局域网。同一个网段内所有主机的网络号完全相同,不同网段的网络号必须不同。
  • 主机号:标识网段内的具体主机。同一网段内,主机号必须唯一,不能重复

我们通过学校学号的例子来带大家理解下IP=网络号+主机号

如上图,一个学校中学生的学号由两部分构成:学生学号 = 学院编号+学生编号

我们规定,一个学生的学号的前两位就是这个学生所在学院的编号,剩余的就是学生编号

有一天计算机学院的张三(学号:01123)捡到了一个钱包,钱包里有学生证,显示的失主的学号为 06321,接下来:

  1. 张三识别该学号:06321,前两位06就说明了该学生不是本计算机学院(子网)的,但是作为学生张三,他也不知道具体是哪一个学院的。所以张三不需要费力的在本学院寻找失主,直接交给院学生会主席
  2. 每一个学院只有院学生会主席才能通过校群(公网)跨院来进行"交流",现在张三把这个学号为06321学生的钱包交给院学生会主席,通过学号前两位06直接定位到机械学院,然后交给机械学院的院学生会主席
  3. 机械学院的院学生会主席拿到钱包后,就会根据学号的后三位321来在本院定位学生,就能找到06321的李四,李四根据随钱包来的张三的电话,也能同张三联系

(1)第一代方案:有类地址(A/B/C/D/E 五类)

TCP/IP 最初设计了一套固定边界的划分方案:根据 IP 地址前几位的特征位,把地址分成 5 大类,每一类的网络号和主机号长度是固定死的

有类地址的局限性:地址浪费极其严重,B 类很快耗尽,A 类大量闲置

  • 绝大多数企业和机构都申请 B 类地址,但实际网络中根本用不完 6 万多台主机,大量 IP 地址被浪费;
  • C 类地址每个只有 254 台主机,不够中大型组织使用;申请多个 C 类又会导致路由表条目爆炸式增长;
  • 核心问题:网络号和主机号的边界是固定的,完全不能灵活调整,无法适配不同规模的网络

(2)第二代方案:CIDR 无类域间路由 + 子网掩码

为了解决有类地址的僵化和浪费问题,行业提出了CIDR(无类别域间路由),这也是现在互联网实际使用的方案

CIDR 取消了 A/B/C 类的固定边界,引入子网掩码来灵活决定网络号的长度:

  • 子网掩码也是 32 位二进制,由连续的 1连续的 0组成;
  • 掩码中1对应的 IP 位,就是网络号;0对应的位,就是主机号;
  • 掩码永远是前面全 1、后面全 0,不会出现 1 和 0 交叉的情况。

IP 地址子网掩码按位与运算 (对应位都为 1,结果才为 1;只要有一个为 0,结果就是 0),最终得到的结果就是该 IP 所属的网络号(网段地址)

简化写法:前缀表示法

不用每次都写全 32 位子网掩码,直接用「IP 地址 / 网络位的位数」表示,这就是 CIDR 前缀。

  • 例如140.252.20.68/24:表示前 24 位是网络号,对应子网掩码255.255.255.0

三类特殊的 IP 地址

  1. 网络地址(网段号)
  • 定义:主机号部分全部为 0的 IP 地址。
  • 作用:代表整个局域网本身,用来标识一个网段,不能分配给任何一台主机。
  • 示例:192.168.1.0/24 就是该网段的网络地址。
  1. 广播地址
  • 定义:主机号部分全部为 1的 IP 地址。
  • 作用:向同一个网段内所有主机同时发送数据,也不能分配给主机。
  • 示例:192.168.1.255/24 就是该网段的广播地址。
  1. 环回地址(Loopback)
  • 定义:127 开头的所有 IP,最常用127.0.0.1
  • 作用:本机网络协议栈测试,发往环回地址的数据包不会离开本机,直接在网络层回环,用来验证本机 TCP/IP 是否正常工作

3.公网和子网

我们常说的公网子网,是计算机网络中一组相对的核心概念。通俗来讲,公网就是面向全球开放的公共互联网,而子网在日常语境中大多指局部范围内的私有内网

(1)子网

子网 = 内网 / 私网 / 局域网(LAN)

这是最普遍的用法,指在局部地理范围内(家庭、办公室、校园、工厂),由多台设备通过交换机、路由器等设备组建的私有内部网络。

  • 核心标识 :使用私网 IP 地址 ,是国际标准预留的专用 IP 段,仅在本地网络内有效,无法直接在公网上被访问。
    全球通用的私网 IP 段有三类:
    • A 类:10.*
    • B 类:172.16.* ~ 172.31.*
    • C 类:192.168.* ~ 192.168.*
  • 覆盖范围:通常几十米到几公里,局限在一个建筑、园区内。
  • 管理主体:由个人、企业或机构自行管理,可自定义网络规则和权限。
  • 典型场景:家里手机、电脑、电视连接同一个 WiFi;公司内部办公电脑、打印机互联;校园内部的教务系统网络等

如上图,我们来学习一下子网/局域网/私网

首先要来介绍一下一个硬件设备------路由器

路由器是网络边界设备,一边连接内部的本地子网,一边连接外部的上级网络,因此一个路由器至少拥有两个 IP 地址,分别对应两侧的网络

  1. LAN口IP == 子网IP(子网网关)
  • 定义 :LAN 口是路由器连接本地内网 的接口,对应的 IP 地址就叫子网 IP,也常被称为「内网网关地址」,是整个子网的 "出口门牌号"。
  • 核心作用
    • 它是子网内所有终端(电脑、手机、打印机)的默认网关,内网设备要跨出子网通信,都必须把数据包先发给这个地址。
    • 它本身就属于这个子网,通常是子网的第一个可用 IP(一般为.1),是子网的管理者。
  • 对应图中的例子
    • 家用路由器的 LAN 口 IP:192.168.1.1/24,它下面连接的电脑都是192.168.1.x,同属192.168.1.0/24这个子网。
    • 运营商路由器的 LAN 口 IP:10.1.1.1/24,它下面连接的所有家用路由器,都属于10.1.1.0/24这个运营商子网
  1. WAN 口 IP = 上级子网的「主机 IP」
  • 定义 :WAN 口是路由器连接外部上级网络的接口,对应的 IP 叫 WAN 口 IP。对上级网络来说,你的路由器只是上级子网里的一台普通设备,WAN 口 IP 就是它在上级网络里的 "身份地址"。
  • 核心本质:WAN 口 IP 不属于本级子网,它是上级网络的一个普通主机 IP。
  • 对应图中的例子
    • 家用路由器的 WAN 口 IP:10.1.1.2/2410.1.1.3/24 ------ 对运营商的10.1.1.0/24子网而言,这些家用路由器和普通电脑没有区别,只是子网里的普通主机,分配了.2.3的主机号。
    • 运营商路由器的 WAN 口 IP:122.77.241.4/24122.77.241.5/24 ------ 对最上层的公网而言,运营商路由器就是公网里的一台普通设备

a.NAT

NAT 全称:Network Address Translation,网络地址转换

本质是在网关设备(路由器、防火墙)上修改 IP 数据包的源地址或目的地址,同时维护地址映射关系,实现私网与公网之间的互通,解决了IPv4地址枯竭问题

NAT 工作在网络层,核心依赖NAT 映射表,整个过程可以概括为 "出去换源 IP,回来换目的 IP,全靠映射表对应"

核心逻辑

  1. 内网主机设备发起公网访问,数据包到达 NAT网关(路由器)
  2. 路由器将数据包源IP 修改为 路由器的WAN口IP,同时在本地映射表中记录「私网 IP: 端口 → 公网 IP: 端口」的对应关系
  3. 数据包转发到公网,目标服务器智只能看到转换后的公网IP,感知不到内网设备
  4. 公网返回的响应数据包到达路由器,路由器查询映射表,把目的公网 IP 换回对应的私网 IP,转发给内网设备

b.内网转发的全流程

如上图;

  • src :全称 Source,意为「源」
  • dst :全称 Destination,意为「目的 / 目标」

服务器回复数据,核心是源 IP 全程不变,目的 IP 每经过一次 NAT 就被换回内层 IP,和去程正好反过来。

  1. 公网服务器发出响应包

服务器回复请求,源地址是自己,目的地址是它看到的请求来源(运营商路由器公网 IP)。

  • src122.77.241.3(服务器自身公网 IP)
  • dst122.77.241.4(请求包的源 IP,即运营商路由器 WAN 口)

服务器根本不知道内网的存在,它只能回复给运营商的公网 IP。

  1. 运营商路由器做第一次目的地址转换

数据包从 WAN 口进入运营商路由器,路由器查询自己的 NAT 映射表,找到对应会话,修改目的 IP。

  • 转换前:src=122.77.241.3,dst=122.77.241.4
  • 转换后:src=122.77.241.3(源 IP 全程不动),dst=10.1.1.2(家用路由器的 WAN 口 IP)
  • 转换完成后,从 LAN 口转发到运营商内网。
  1. 家用路由器做第二次目的地址转换

数据包从 WAN 口进入家用路由器,路由器查询本地 NAT 映射表,找到对应的内网主机。

  • 转换前:src=122.77.241.3,dst=10.1.1.2
  • 转换后:src=122.77.241.3(源 IP 依然不变),dst=192.168.1.201(家庭主机的私网 IP)
  • 转换完成后,从 LAN 口转发给家庭主机。
  1. 家庭主机收到响应
  • 主机最终收到的数据包:src=122.77.241.3,dst=192.168.1.201
  • 主机视角:它以为自己直接和公网服务器通信,完全感知不到中间经过了两级 NAT 转换

(2)公网

公网也叫广域网(WAN)、互联网,是由全球各地运营商、机构、个人的网络互相连接组成的全球性公共网络,是我们上网访问外部服务的基础。

  • 核心标识 :使用公网 IP 地址 ,由国际互联网管理机构统一分配,全球唯一,可直接被互联网上的其他设备寻址和访问。
  • 覆盖范围:无地域限制,跨城市、跨国家、跨运营商,覆盖全球所有接入互联网的节点。
  • 管理主体:由各大运营商、互联网组织分布式维护,没有单一的管理方。
  • 典型场景 :浏览网页、刷视频、发送邮件、跨境文件传输等所有跨地域的网络交互,都基于公网完成

    国外俄罗斯访问目标地址 5.1.16.X
  1. 俄罗斯路由器查路由表,匹配到5.0.0.0/8属于中国,下一跳指向中国路由器的 WAN 口,数据包发往国际骨干网
  2. 中国国家级路由器收到包,匹配到5.1.0.0/16属于陕西,下一跳指向陕西路由器的 WAN 口,数据包发往国内骨干网
  3. 陕西省级路由器收到包,匹配到5.1.16.0/20属于西安,下一跳指向西安路由器的 WAN 口
  4. 西安市级路由器收到包,转发到对应内网的目标主机

河北的报文发往 5.1.16.X

  1. 河北路由器查路由表,匹配到5.1.0.0/16属于陕西,下一跳指向陕西省级路由器,数据包进入国内骨干网
  2. 陕西省级路由器收到包,匹配到5.1.16.0/20属于西安,转发到西安路由器
  3. 西安路由器最终转发到目标主机

4.路由

路由就是在复杂的网络拓扑中,为 IP 数据包选择一条通往目标地址的传输路径的过程,是 IP 网络层的核心功能

IP 数据包不需要提前知道完整路径,每到达一个节点(主机 / 路由器),就查询本地的路由表,确认 "下一站往哪走",然后转发出去,一站一站最终抵达终点。

  • 每个节点只需要知道下一跳,不需要知道全程路径,这是互联网路由的核心设计思想

路由表可以使⽤route命令查看:

默认路由(default) :特殊的网关路由,目的地址为0.0.0.0/0,是路由表的 "兜底规则"------ 当所有具体路由都匹配失败时,就走默认路由

路由转发的核心算法是最长掩码匹配原则:将目的 IP 和路由表中每条的子网掩码做 "与运算",得到对应的网络地址;匹配成功的条目中,子网掩码越长(网络位越多),优先级越高

结尾

ok了,这一期关于IP网络层的讲解就到这了,感谢你的学习观看,我们下期再见

往期回顾

  1. 【Linux】第13期 详解应用层协议HTTP+Cookie/Session+HTTPS
  2. 【Linux】第12期 应用层自定义协议和序列化 + 进程组、会话与守护进程深度解析
  3. 【Linux】第11期 详解Linux网络基础+socket编程
相关推荐
zx_741484811 小时前
【Linux入门】常用基本命令(一)——帮助、文件目录操作、时间日期与用户组管理
linux·服务器
AutumnWind04201 小时前
【Shell 知识速查表】
linux
风哥2号1 小时前
数据库教程FGMT04‑生产环境Linux+Oracle19c RAC集群安装配置与项目实战
linux·数据库
陈年老古董1 小时前
Python模拟MapReduce分治思想 | 从单文件统计到大文件拆分聚合 学习笔记
开发语言·hadoop·笔记·python·学习
qetfw1 小时前
Debian Postfix + Dovecot 基础配置:DNS、Maildir、IMAP 与邮件队列验证
linux·服务器·网络·debian
weixin_446260851 小时前
PromptMatic:通过多阶段提示优化提升大模型的指令遵循能力
运维·服务器
j7~1 小时前
【Linux】三十五.网络基础(三)《从零实现一个C++ HTTP服务器:完整项目实战》----万字详解
运维·网络协议·http·网络层·服务层·协议层·http的实现
吴声子夜歌1 小时前
Shell脚本——数组
linux·运维·shell
Web极客码2 小时前
GPT-6 Astra 上手体验:如何让编码代理真正提速
服务器·gpt·ai·大模型·astra