网络层IP协议

基本概念

IP主机定位 &&路由选择

TCP提供各种策略 (丢包重传,流量控制,拥塞控制等),使得数据从A点跨网络传输到B点可靠

IP作用 :提供一种能力,将数据从A点---跨网络---送到B点,真正的执行者.

IP协议如何进行主机定位和报文转发?

1.根据目的IP,进行局域网之间的转发.

2.局域网内,进行内网的转发

bash 复制代码
IP = 目标子网 + 目标主机

基本概念

主机: 配有IP地址, 也要进行路由控制的设备;

路由器: 即配有IP地址, ⼜能进⾏路由控制;

节点: 主机和路由器的统称;

协议头格式


4位首部长度 :表示IP头部的长度(单位:32bit),即长度×4字节。
[0,15] × 4字节 = [ 0,60 ] 字节,所以选项长度为 [0-40] 字节

4位版本号(version) :指定IP协议的版本,对于IPv4来说,值为4。

16位总长度(total length) :表示IP数据报整体的字节数---报头+有效载荷总共的大小.

次要: 8位服务类型(Type Of Service):包含3位已弃用的优先权字段、4位TOS字段和1位必须置为0的保留字段。4位TOS分别对应:最小延时、最大吞吐量、最高可靠性、最小成本(四者相互冲突,仅能选其一)。例如ssh/telnet优先最小延时,ftp优先最大吞吐量.


8位生存时间(Time To Live, TTL) :数据报到达目的地的最大跳数,默认通常为64. 每经过一个路由,TTL减1,减至0仍未到达则丢弃报文(用于防止路由循环).

8位协议 :表示上层的协议类型(如TCP和UDP)

16位头部校验和:通过CRC校验鉴别IP头部是否损坏。


16位标识(id):唯一标识主机发送的报文,若IP报文在数据链路层被分片,所有分片的id均相同.

3位标志字段

  • 第一位:保留(暂未使用,未来可能启用).
  • 第二位:置1表示禁止分片,若报文长度超过MTU,IP模块会丢弃该报文.
  • 第三位:表示"更多分片",分片后最后一个分片置0,其余分片置1(类似结束标记).

13位分片偏移(fragment offset):表示分片相对于原始IP报文起始位置的偏移,实际偏移字节数=该值×8.因此除最后一个报文外,其他报文长度必须是8的整数倍(保证报文连续).


32位源地址和32位目标地址:分别表示报文的发送端IP和接收端IP。

网段划分

IP地址的基本结构

IP地址分为两个部分,网络号和主机号

  • 网络号:用于区分不同的网段,保证相互连接的两个网段具有不同的标识
  • 主机号 :用于标识同一网段内的不同设备,同一网段内主机号必须互不重复 .

不同的子网的本质其实就是把网络号相同的主机放在一起.

传统分类地址的局限性

类别 地址范围 特点与问题
A 类 0.0.0.0 ~ 127.255.255.255 网段极大,主机数过多,地址浪费严重
B 类 128.0.0.0 ~ 191.255.255.255 被大量组织申请,很快耗尽
C 类 192.0.0.0 ~ 223.255.255.255 网段较小,灵活性不足
D 类 224.0.0.0 ~ 239.255.255.255 组播地址
E 类 240.0.0.0 ~ 247.255.255.255 保留地址

核心问题

  • 固定类别划分导致地址利用率极低(如 B 类网段可容纳 6 万 + 主机,但实际场景中很少需要这么多).
  • 地址分配不均衡,B 类地址耗尽而 A 类地址大量闲置.

CIDR与子网掩码(现代解决方案)

为解决传统分类的问题,提出CIDR(无类别域间路由)技术,核心是通过子网掩码灵活划分网络号与主机号。

核心概念
子网掩码 :32 位二进制数,用连续的1表示网络位 ,连续的0表示主机位。
CIDR 前缀(/x)子网掩码的简写形式 ,x代表前x位为网络位,剩余32-x位为主机位。
网络号计算 :将 IP 地址与子网掩码做按位与运算,结果即为该 IP 所属的网络号。
可用主机数:2^(主机位数) - 2(减去网络地址和广播地址,这两个地址不可分配给主机)。

规律:前缀每增加 1,子网数翻倍,可用主机数减半

例子:

子网掩码: 255.255.255.0

32位二进制: 1111 1111 (.) 1111 1111 (.) 1111 1111 (.) 0000 0000

CIDR 前缀: /24 (前24位为网络号)

某IP地址: 140.252.20.68

32位二进制: 1000 1100 (.) 1111 1100 (.) 0001 0100 (.) 0100 0100
取前24位按位与32位二进制的子网掩码 作为网络号:
1000 1100 (.) 1111 1100 (.) 0001 0100 (/) 0000 0000(后8位归0)

  • 网络号为: 140.252.20.0
  • 主机号范围: 140.252.20.1 ~ 140.252.20.254(可用主机数28−2=2542^8 - 2 = 25428−2=254)
    • 网段起始(网络地址):140.252.20.0
    • 网段结束(广播地址):140.252.20.255

IP 地址自动化管理:DHCP

手动管理子网内 IP 地址繁琐且易出错,DHCP(动态主机配置协议) 可自动为子网内设备分配 IP 地址:

  • 路由器通常集成 DHCP 功能,可作为 DHCP 服务器.
  • 功能:自动分配 IP 地址、子网掩码、网关、DNS 等网络参数,避免手动配置的不便与冲突.

特殊IP地址

  • IP地址中的主机地址 全部设置成0,就成了网络地址,代表这个局域网.

  • IP地址中的主机地址 全部设置成1,就成了广播地址,用于给同⼀个链路中相互连接的所有主机发送数据包.

  • 127.*的IP地址用于本机环回(loop back)测试,通常是127.0.0.1

IP地址的数量

IP地址(IPv4)是一个4字节32位的正整数.那么一共只有2的32次方个IP地址,大概是43亿左右.

而TCP/IP协议规定,每个主机都需要有一个IP地址.

这意味着,一共只有43亿台主机能接入网络么?

实际上,由于一些特殊的IP地址的存在,数量远不足43亿.

另外IP地址并非是按照主机台数来配置的,而是每一个网卡都需要配置一个或多个IP地址.

CIDR在一定程度上缓解了IP地址不够用的问题(提高了利用率,减少了浪费,但是IP地址的绝对上限并没有增加),仍然不是很够用.

这时候有三种方式来解决:

  • 动态分配IP地址:只给接入网络的设备分配IP地址.因此同一个MAC地址的设备,每次接入互联网中,得到的IP地址不一定是相同的
  • NAT技术
  • IPv6:IPv6并不是IPv4的简单升级版.这是互不相干的两个协议,彼此并不兼容.IPv6用16字节128位来表示一个IP地址.但是目前IPv6还没有普及.

私有IP地址和公网IP地址

私有IP地址:内网,子网,局域网.

公网IP地址:入公网,才能入互联网.

  • 10.*,前8位是网络号,共16,777,216个地址
  • 172.16.* 到 172.31.*,前12位是网络号,共1,048,576个地址
  • 192.168.*,前16位是网络号,共65,536个地址

包含在这个范围中的,都称为私有IP ,其余的则称为全局IP (或公网IP).

私有IP在自己所在的网络中不会重复,但是如果是不同的局域网,IP可能会重复.

WAN 口 IP

  • 路由器上联口 ,用来接外网/上级网络
  • 上级设备(光猫、公司网关、上级路由器)分配
  • 作用:让路由器能访问外面的网络
  • 例子:192.168.1.10010.0.0.5、公网IP

LAN 口 IP = 局域网IP = 子网IP

都是拥有内网的网关IP

这三个本质是一回事,只是叫法不同:

  • LAN 口 IP:路由器自己在局域网里的地址
  • 局域网IP:整个内网设备用的 IP 段
  • 子网IP:这个局域网的网段

路由器天生就是跨两个网络的设备:

  1. WAN 侧网络(外网/上级网)
  2. LAN 侧网络(内网)

它的工作就是:
把内网数据包转发到外网,把外网数据包带回内网。

总结:

  • WAN 口 IP :路由器对外的地址(连外面)
  • LAN 口 IP / 局域网IP / 子网IP :路由器对内的地址(连你设备)
  • 路由器就是靠 WAN 在一个网、LAN 在另一个网横跨两个网络
关于NAT技术

核心瓶颈:公网 IP 真的 "不够用"

在互联网早期,每台联网设备都需要一个唯一的公网 IP。

NAT 的核心魔法:地址复用

NAT 让同一个公网 IP 同时承载成百上千个设备的连接

从一个家用设备发送一个请求到目标主机时,每传递到上一级设备(路由器),都要把src来源IP改成这个设备的WAN口IP,这样传递到广域网的时候,都是公网IP,只要不同公网IP进行通信即可.

注意在公网中的IP是可以确定的(公网中的IP是唯一的),而在内网中的IP是不能直接确定的.(不同的内网中,主机的IP可能相同)

如上有个问题,消息发送出去,已经走通(即,从内网到公网),那么从公网到内网,这个倒回来的过程,似乎用上面的方法回不来(每次源IP都被替换成WAN口IP),如何解决?

NAPT---NAT地址转化表

如果局域网内, 有多个主机都访问同⼀个外网服务器, 那么对于服务器返回的数据中, 目的IP都是相同的. 那么NAT路由器如何判定将这个数据包转发给哪个局域网的主机?

使用IP+port来建立这个关联关系

这种关联关系也是由NAT路由器自动维护的. 例如在TCP的情况下, 建立连接时, 就会生成这个表项. 在断开连接后, 就会删除这个表项.

这样从公网的某个服务器返回,当前主机的时候,就可以根据路由器中维护的NAPT,进行返回.

如下是NAT 技术和互联网架构的核心逻辑

关于公网

路由

路由就是在复杂网络中,为数据包找到一条通往终点的路径 ,核心是逐跳转发(Hop by Hop)

  • 像"唐僧问路"一样,每到一个网络节点(路由器/主机),就查询下一步该往哪走。
  • 每一跳(Hop)是数据链路层的一个区间:在以太网中,就是源MAC地址到目的MAC地址的帧传输段。
  • IP层负责端到端 的最终目标通信,数据链路层负责每一跳的局部传输。

逐跳转发流程

  1. 数据包到达路由器 :路由器先解析数据包的目的IP地址
  2. 查询路由表:根据目的IP,在本地路由表中匹配最优下一跳。
  3. 决定转发方向
    • 若目的IP与直连网段匹配:直接通过对应接口发送给目标主机。
    • 若不匹配:转发给下一个路由器,继续重复"查询-转发"流程。
  4. 最终到达:数据包经过多跳转发,最终抵达目的IP所在主机。

路由表核心解析

路由表是每个网络节点维护的"指路地图",核心字段如下:

字段 含义
Destination 目标网络地址(要去往的网段)
Gateway 下一跳地址(数据包要交给的下一个设备)
Genmask 子网掩码(用于匹配目的IP)
Flags 路由状态标志: • U:此条路由有效 • G:下一跳是路由器(需转发) • 无G:目标是直连网段(无需转发)
Iface 数据包要从哪个网络接口发出
Metric 路由开销(值越小优先级越高)

关键规则

  • 最长前缀匹配 :目的IP会和路由表中子网掩码最长的条目优先匹配。
  • 默认路由(default) :当所有条目都不匹配时,走最后一条默认路由,通常指向网关路由器

例子: 完整路由表(route -n 输出)

bash 复制代码
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG    100    0        0 eth0
192.168.1.0     0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.10.0    0.0.0.0         255.255.255.0   U     0      0        0 eth1
127.0.0.0       0.0.0.0         255.0.0.0       U     0      0        0 lo

通常用户主机访问其他公网IP时,是一路跳网关路由器到公网.

例1:目的IP在直连网段

  • 目的IP:192.168.56.3
  • 匹配过程:
    1. 192.168.10.0/24做按位与 → 192.168.56.0,不匹配。
    2. 192.168.56.0/24做按位与 → 192.168.56.0,匹配成功。
  • 转发动作:
    • eth1接口直接发送,因为是直连网段,不需要经过路由器转发

例2:目的IP在外部网络

  • 目的IP:202.10.1.2
  • 匹配过程:
    1. 与所有直连网段匹配,均不匹配。
    2. 匹配最后一条默认路由(default)
  • 转发动作:
    • eth0接口发出,交给网关192.168.10.1路由器。
    • 后续由192.168.10.1继续查询它的路由表,决定下一步。

IP分片与组装


16位标识(id) :唯一标识主机发送的报文,若IP报文在数据链路层被分片,所有分片的id均相同.

3位标志字段

  • 第一位:保留(暂未使用,未来可能启用).
  • 第二位:置1表示禁止分片,若报文长度超过MTU,IP模块会丢弃该报文.
  • 第三位:表示"更多分片",分片后最后一个分片置0,其余分片置1(类似结束标记).

13位分片偏移(fragment offset) :表示分片相对于原始IP报文起始位置的偏移.

  • 偏移量必须是8的整数倍
  • 写入偏移量,实际写入偏移量数据:真实偏移量/8 → x >> 3
  • 提取偏移量,偏移量×8 = 真实偏移量 → x << 3

接收方:收到大量的IP报文,多个客户端发来的IP报文,有的分片了有的没分片.

  1. 该报文是否分片

    • 没有分片 : 更多分片 == 0 && 片偏移 == 0

    • 分片了 :第一片,中间片,最后一片

      位置 16位标识(id) 3位标志字段 13位分片偏移
      起始片 id 1 第三位更多分片位为1 0
      中间片 id 2 第三位更多分片位为1 !0
      ... ... ... ...
      结尾片 id n 第三位更多分片位为0 !0
  2. 保证收到所有的分片(收全所有分片)

    如何保证?

    • 第一片:起始片片偏移一定是0,如果没有,就丢失了
    • 中间片 :前一个报文的片偏移+前一个报文的大小 = 下一个报文的片偏移,不符合,那就是丢了
    • 结尾片:更多分片标志位为0,如果没有就是丢失了

分片与组装

1. 数据链路层:MTU的限制

  • MTU(最大传输单元) :以太网默认 MTU = 1500 字节,这是数据链路层一次能传输的最大帧载荷长度

2. 网络层:IP分片的代价

  • 网络层会告知传输层(TCP):请将报文控制在 1480 字节以内1500 - 20字节IP首部)。
  • 若TCP报文超过1480字节,IP层就需要:
    1. 把大报文拆分成多个更小的IP分片。
    2. 每个分片独立传输,到达对端后再由目标主机的IP层重新组装
  • 风险:任何一个分片丢失,整个原始数据报都要重传,会显著增加丢包率和延迟。

3. 传输层(TCP):主动规避分片

  • TCP通过**滑动窗口 + MSS(最大分段大小)**机制,主动将大数据拆分成多个不超过 MSS = MTU - IP首部 - TCP首部(通常为1460字节)的报文段。
  • 这样IP层收到的报文天然小于MTU,无需分片,直接封装成帧传输,避免了分片组装带来的性能损耗和丢包风险。

补充:MSS与MTU的关系

text 复制代码
MTU = 1500 字节(以太网)
└─ IP首部 = 20 字节(无选项时)
└─ TCP首部 = 20 字节(无选项时)
→ MSS = 1500 - 20 - 20 = 1460 字节

TCP会在三次握手时协商双方的MSS,确保传输的报文段不会超过对端的MTU限制。

分片组装实例

假设在IP层,有一个大小为3000字节的报文,如何分片?如何组装?

分片

首先有效载荷为2980(去除了20字节的IP报头),如下是对2980进行分片

组装

  1. 接收方怎么知道分片了?

    • 如果没有分片 MF=0 && 片偏移=0
    • MF != 0 || 片偏移 != 0
  2. server怎么保证收全了

    • 16标识相同的聚合在一起
    • 分片收全了,考虑分片丢失
      • 第一片丢了
        没有片偏移为0的报文
      • 最后一片丢了
        标志为0的报文缺失了
      • 中间丢失
        收到的所有分片,按照片位移排序,进行升序排序,偏移量×8 + 自己有效载荷大小 = 下一片的偏移量
相关推荐
一招定胜负2 小时前
大模型的云端部署:flask部署模型简单案例
智能路由器
WX:ywyy67982 小时前
短剧付费转化系统:试看、卡点、解锁、会员全链路商业化设计
网络·短剧·短剧app·短剧系统·短剧系统开发·短剧app开发·短剧系统搭建
tritone2 小时前
最近在学习网络配置中的Port Forwarding(端口转发)技术,为了有个稳定的实验环境,我试用了阿贝云的免费虚拟主机和免费云服务器
服务器·网络·学习
橘子132 小时前
NAT,代理服务,内网穿透
网络·智能路由器
文静小土豆2 小时前
Docker 网络配置指南:Bridge、Host、None、Container 全攻略
网络·docker·容器
white-persist2 小时前
【CTF线下赛 AWD】AWD 比赛全维度实战解析:从加固防御到攻击拿旗
网络·数据结构·windows·python·算法·安全·web安全
_OP_CHEN4 小时前
【Linux网络编程】(一)初识计算机网络:从独立主机到协议世界的入门之旅
linux·服务器·网络·网络协议·计算机网络·socket·c/c++
一袋米扛几楼988 小时前
【密码学】CrypTool2 工具是什么?
服务器·网络·密码学
南棱笑笑生11 小时前
20260310在瑞芯微原厂RK3576的Android14查看系统休眠时间
服务器·网络·数据库·rockchip