基本概念
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.100、10.0.0.5、公网IP
② LAN 口 IP = 局域网IP = 子网IP
都是拥有内网的网关IP
这三个本质是一回事,只是叫法不同:
- LAN 口 IP:路由器自己在局域网里的地址
- 局域网IP:整个内网设备用的 IP 段
- 子网IP:这个局域网的网段
路由器天生就是跨两个网络的设备:
- WAN 侧网络(外网/上级网)
- 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层负责端到端 的最终目标通信,数据链路层负责每一跳的局部传输。
逐跳转发流程
- 数据包到达路由器 :路由器先解析数据包的目的IP地址。
- 查询路由表:根据目的IP,在本地路由表中匹配最优下一跳。
- 决定转发方向 :
- 若目的IP与直连网段匹配:直接通过对应接口发送给目标主机。
- 若不匹配:转发给下一个路由器,继续重复"查询-转发"流程。
- 最终到达:数据包经过多跳转发,最终抵达目的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 - 匹配过程:
- 与
192.168.10.0/24做按位与 →192.168.56.0,不匹配。 - 与
192.168.56.0/24做按位与 →192.168.56.0,匹配成功。
- 与
- 转发动作:
- 从
eth1接口直接发送,因为是直连网段,不需要经过路由器转发。
- 从
例2:目的IP在外部网络
- 目的IP:
202.10.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报文,有的分片了有的没分片.
-
该报文是否分片
-
没有分片 :
更多分片 == 0&&片偏移 == 0 -
分片了 :第一片,中间片,最后一片
位置 16位标识(id) 3位标志字段 13位分片偏移 起始片 id 1 第三位更多分片位为1 0 中间片 id 2 第三位更多分片位为1 !0 ... ... ... ... 结尾片 id n 第三位更多分片位为0 !0
-
-
保证收到所有的分片(收全所有分片)
如何保证?
- 第一片:起始片片偏移一定是0,如果没有,就丢失了
- 中间片 :
前一个报文的片偏移+前一个报文的大小 = 下一个报文的片偏移,不符合,那就是丢了 - 结尾片:更多分片标志位为0,如果没有就是丢失了
分片与组装

1. 数据链路层:MTU的限制
- MTU(最大传输单元) :以太网默认
MTU = 1500 字节,这是数据链路层一次能传输的最大帧载荷长度。
2. 网络层:IP分片的代价
- 网络层会告知传输层(TCP):请将报文控制在 1480 字节以内 (
1500 - 20字节IP首部)。 - 若TCP报文超过1480字节,IP层就需要:
- 把大报文拆分成多个更小的IP分片。
- 每个分片独立传输,到达对端后再由目标主机的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进行分片

组装
-
接收方怎么知道分片了?
- 如果没有分片 MF=0 && 片偏移=0
- MF != 0 || 片偏移 != 0
-
server怎么保证收全了
- 16标识相同的聚合在一起
- 分片收全了,考虑分片丢失
- 第一片丢了
没有片偏移为0的报文 - 最后一片丢了
标志为0的报文缺失了 - 中间丢失
收到的所有分片,按照片位移排序,进行升序排序,偏移量×8 + 自己有效载荷大小 = 下一片的偏移量
- 第一片丢了