3、网络层核心:IP协议、IPv4与IPv6、子网掩码与CIDR、路由选择基础
聊到网络层,IP协议绝对是绕不开的主角。我刚开始做全栈开发那会儿,总觉得IP层离应用层太远,写业务代码根本用不上。直到有一次排查线上超时问题,抓包一看,发现数据包在路由节点之间来回跳了二十多跳还没到目的地……嗯,从那以后我再也不敢小看网络层了。
说白了,网络层就是负责把数据包从源主机送到目标主机。它不关心你传的是什么内容,也不保证一定能送到——那是传输层的事。它只做一件事:寻址和转发。
IP协议:互联网的“通用语言”
IP协议的全称是Internet Protocol,它定义了数据包在网络中传输的格式和规则。每个数据包都包含一个头部,里面最重要的就是源IP地址和目标IP地址。
我习惯把IP协议比作快递单上的寄件人和收件人地址。没有这个地址,数据包在网络里就是无头苍蝇。IP协议的核心能力有两个:
- 寻址:给每台设备分配一个唯一的逻辑地址
- 分片与重组:当数据包太大,超过链路层的MTU时,IP层会把它切成小块,到了目的地再拼回去
IPv4:老当益壮,但地址快用完了
IPv4地址是32位的,通常写成点分十进制,比如 192.168.1.1。理论上可以提供约43亿个地址。你想想看,全球几十亿人,每人手里好几台设备,这点地址哪够用?
IPv4地址的结构分为两部分:网络号和主机号。网络号标识你所在的网络段,主机号标识你在该网络里的具体设备。
举个例子:192.168.1.0/24 这个网段里,192.168.1 是网络号,最后一个 0 是主机号范围。为什么是 /24?这个我们后面讲CIDR的时候再说。
IPv4地址还分成了几类:
| 类别 | 起始位 | 地址范围 | 用途 |
|---|---|---|---|
| A类 | 0 | 1.0.0.0 - 126.255.255.255 | 大型网络 |
| B类 | 10 | 128.0.0.0 - 191.255.255.255 | 中型网络 |
| C类 | 110 | 192.0.0.0 - 223.255.255.255 | 小型网络 |
| D类 | 1110 | 224.0.0.0 - 239.255.255.255 | 组播 |
| E类 | 1111 | 240.0.0.0 - 255.255.255.255 | 保留 |
IPv6:下一代协议,地址多到用不完
IPv4地址枯竭是个老生常谈的问题。IPv6把地址长度扩展到了128位,写成8组16进制数,比如 2001:0db8:85a3:0000:0000:8a2e:0370:7334。
128位是什么概念?地球上每粒沙子都能分到一个IP地址。你想想看,这得有多大的空间。
IPv6相比IPv4有几个明显的变化:
- 头部更简洁:固定40字节,没有选项字段,路由器处理更快
- 内置安全:IPSec是IPv6的标配,不是可选项
- 自动配置:设备可以自动生成链路本地地址,不需要DHCP
- 没有广播:用组播和任播代替广播,减少网络噪音
我个人习惯在开发环境里同时启用IPv4和IPv6双栈。虽然大部分云服务商还是以IPv4为主,但IPv6的普及速度比我想象中快。我记得去年帮一个客户做物联网项目,他们的设备全部走IPv6,因为设备数量实在太多了,IPv4根本不够分。
子网掩码与CIDR:告别浪费,精准划分
子网掩码是个32位的数字,和IP地址做“与”运算,就能得到网络号。比如 255.255.255.0 表示前24位是网络号,后8位是主机号。
但子网掩码有个问题——它太死板了。你只能按8位、16位、24位这种边界来划分网络。这就导致了很多浪费。比如一个公司需要300个IP地址,用C类(254个)不够,用B类(65534个)又太多。
CIDR(无类别域间路由)就是来解决这个问题的。它用 /数字 来表示网络前缀的长度,不再受限于A、B、C类的边界。
举个例子:
192.168.1.0/24 → 网络号24位,主机号8位,可用地址254个
192.168.1.0/25 → 网络号25位,主机号7位,可用地址126个
192.168.1.0/26 → 网络号26位,主机号6位,可用地址62个
你看,通过CIDR,我们可以精确地划分出刚好够用的地址段。我在做微服务架构设计时,经常用CIDR来规划不同服务的网络段,避免地址冲突。
减2是因为网络地址和广播地址不能用。
路由选择基础:数据包是怎么找到路的?
路由选择,说白了就是路由器决定把数据包往哪扔。每个路由器都维护着一张路由表,里面记录着目标网络和下一跳地址的对应关系。
路由选择分两种:
- 静态路由:管理员手动配置。适合小网络,稳定但维护成本高
- 动态路由:路由器之间自动交换信息。适合大型网络,灵活但复杂
动态路由协议又分两类:
| 类型 | 协议 | 特点 |
|---|---|---|
| 距离矢量 | RIP | 基于跳数,简单但收敛慢 |
| 链路状态 | OSPF | 基于链路状态,收敛快,适合大型网络 |
| 路径矢量 | BGP | 互联网核心协议,基于AS路径 |
我曾经在调试一个跨地域的微服务调用时,发现请求总是超时。抓包一看,数据包从北京绕到了美国,再绕回上海。原因是BGP路由表里有一条更优的路径没有被选上。后来调整了AS路径的权重,问题才解决。
路由选择的核心原则是最长前缀匹配。什么意思呢?就是路由表里如果有多个条目匹配目标地址,路由器会选择前缀最长的那个。比如目标地址是 192.168.1.100,路由表里有 192.168.0.0/16 和 192.168.1.0/24,路由器会选后者,因为它的前缀更长,更精确。
嗯,网络层的内容就聊到这儿。下一章我们讲传输层,到时候会聊到TCP的三次握手和四次挥手——那可是面试高频考点,也是实际开发中经常踩坑的地方。