计算机网络:自顶向下方法 - Day 9 | 网络层概述、数据平面与路由器工作原理
Day 9 — 网络层概述、数据平面与路由器工作原理#
前情回顾:Day 7 我们聊了 UDP 和可靠数据传输原理,Day 8 深入 TCP 的拥塞控制。传输层的故事暂时告一段落——但你会发现,不管 TCP 还是 UDP,它们都建立在一个假设之上:网络层会把数据从源送到目的。这个”网络层”到底怎么送的?今天我们终于要打开这个黑盒,看看互联网的”快递分拣中心”——路由器——是怎么工作的。
一、网络层是个什么层?#
1.1 从传输层到网络层#
回顾一下我们的五层模型:
1 | 应用层 ← HTTP, DNS, SMTP... |
传输层的 TCP/UDP 负责端到端的通信(进程到进程),而网络层负责主机到主机的通信。你可以理解为:
- 传输层:你给快递员打电话说”请把这个包裹送到张三家,交给张三本人”(进程到进程,端口寻址)
- 网络层:快递分拣中心看地址,决定这个包裹要从北京发到上海(主机到主机,IP 寻址)
🎯 生活类比:传输层像是快递单上的收件人姓名和电话(具体到人),网络层像是收件地址里的城市和街道(具体到地方)。你写的快递单两层信息缺一不可,网络世界也一样。
1.2 网络层的两大功能#
网络层可以说是整个互联网最忙的一层,它有两个核心功能:
① 转发(Forwarding)——数据平面
当一个数据包到达路由器的某个输入端口,路由器要决定:这个包该从哪个输出端口送出去?这个决策是本地的、即时的,就在路由器内部完成。
② 路由(Routing)——控制平面
路由器们需要互相交流,搞清楚整个网络的拓扑结构,然后在每台路由器上建立起转发表(Forwarding Table),告诉转发逻辑”遇到去某个网络的包,应该从哪个端口送出去”。这个决策是全局的、慢速的,需要路由协议(如 OSPF、BGP)的参与。
| 对比项 | 转发(数据平面) | 路由(控制平面) |
|---|---|---|
| 时间尺度 | 纳秒级(每个包都要处理) | 秒~分钟级(拓扑变化才更新) |
| 作用范围 | 单个路由器内部 | 整个网络/自治系统 |
| 关键设备 | 路由器的硬件/软件 | 路由协议和算法 |
| 类比 | 快递员看地址分拣包裹 | 快递公司规划物流线路 |
🎯 生活类比:想象一个巨大的快递分拣中心。转发就是传送带上的包裹到了一个分叉口,工作人员看一眼邮编,推到对应的滑道里——这个动作每秒发生几百万次。路由则是公司的调度部门根据全国道路情况、新开的网点、拥堵的高速,定期更新一份”路由指南”发到每个分拣中心——这个动作可能一天才更新一次。
1.3 数据平面 vs 控制平面#
这是第 8 版书里特别强调的一个架构视角:
1 | ┌─────────────────────────────────────────┐ |
数据平面是路由器的”肌肉”——快速、机械、每包执行。通常用硬件(ASIC、FPGA)实现,追求速度。
控制平面是路由器的”大脑”——思考、协商、更新。通常用软件实现,运行路由协议进程。
传统路由器把这两个功能合在一台设备里。但 SDN(Software-Defined Networking,软件定义网络)的革命性思想就是:把控制平面从路由器里抽出来,放到一个集中的控制器上。就像连锁快餐店把菜单决策权从每家门店收回总部——门店只管按菜单做菜(转发),总部负责研发新品和调整策略(路由)。
🔧 实战关联:你家跑 OpenWrt 的路由器就是一个完整的传统路由器。OpenWrt 里
ip route显示的 routing table 就是控制平面维护的转发表,而路由器芯片内部的硬件转发芯片(如 MediaTek/Qualcomm 的 SoC)就是数据平面。当你跑tc qdisc做流量整形时,你其实是在数据平面上动手脚!
二、路由器的”解剖图”#
现在让我们打开路由器的外壳,看看里面长什么样。一个通用的路由器架构如下:
1 | 输入端口 交换结构 输出端口 |
路由器由四大组件构成:
- 输入端口(Input Ports)
- 交换结构(Switching Fabric)
- 输出端口(Output Ports)
- 路由处理器(Routing Processor)
我们逐一拆解。
三、输入端口:门口的”安检+导航员”#
3.1 输入端口的三层结构#
输入端口不止是一个”网线口”那么简单。它从物理层到网络层都有处理逻辑:
1 | ┌──────────────────────────────────┐ |
🎯 生活类比:输入端口就像公司大楼的前台。物理层是保安检查你的车有没有停对位置,链路层是前台确认你是不是从合作公司来的(链路层帧),网络层是前台查访客系统,决定你应该去几楼哪个会议室。
3.2 最长前缀匹配(Longest Prefix Matching)#
这是输入端口网络层的核心工作。转发表大概长这样:
| 目的网络前缀 | 输出接口 | 下一跳 |
|---|---|---|
| 11001000.10101010.00000000.00 | 接口0 | — |
| 11001000.10101010.10100000.00 | 接口1 | — |
| 11001000.10101010. | 接口2 | — |
| 0.0.0.0/0(默认路由) | 接口3 | 网关 |
当一个目的 IP 为 192.168.160.1(11001000.10101010.10100000.00000001)的包到达时,路由器需要在表里找最匹配的那一条。
- 第一条
...00000000.00/26不匹配 - 第二条
...10100000.00/26匹配!26 位前缀 - 第三条
192.168.x.x/16也匹配,但只有 16 位前缀
最长前缀匹配的规则是:选择匹配位数最多的那条——这里是第二条(26 位 > 16 位),从接口 1 输出。
🎯 生活类比:你寄快递写的地址是”北京市海淀区中关村大街1号”。快递分拣中心有一张表:
- “北京市” → 发到北京转运中心
- “北京市海淀区” → 发到海淀分部
- “北京市海淀区中关村” → 发到中关村网点
三个都匹配,但当然选最精确的那个——最长的前缀匹配!
3.3 为什么要在输入端口做查找?#
你可能会问:为什么不把包直接送给路由处理器(CPU)去查表?因为太慢了!
现代骨干路由器每个端口要处理 100Gbps 甚至 400Gbps 的流量。每个包的转发决策必须在纳秒级完成。如果每个包都走 CPU 查表,CPU 早就累趴了。所以输入端口上有专用的硬件查找引擎(TCAM,三态内容寻址存储器),一个时钟周期就能完成查找。
🔧 实战关联:在 OpenWrt 上跑
ip route get 8.8.8.8,你看到的就是路由查找的结果。你的家用路由器虽然速度不比骨干路由器,但原理一样——每个到达的包都要走一遍这个查找过程。当你用 frp 做内网穿透时,frp 服务器收到的数据包要转发到你内网的服务,这个过程中经过的每一个路由器都在做最长前缀匹配。
四、交换结构:路由器的”十字路口”#
查完表,知道了包该从哪个输出端口出去,接下来就是把包从输入端口送到输出端口。这个”搬运”动作就是交换结构要干的事。
有三种经典的交换方式:
4.1 经内存交换(Switching via Memory)#
最早的路由器其实就是一台普通计算机,用 CPU 来”交换”:输入端口把包写入内存,CPU 再从内存读出来写到输出端口。
1 | 输入端口 ──▶ [ 内存 ] ──▶ 输出端口 |
优点:简单,用现成的硬件就行。
缺点:慢!每个包要两次内存访问(读+写),而且 CPU 要介入。如果内存带宽是 B,那最大吞吐量是 B/2。而且 CPU 处理速度有限。
🎯 生活类比:就像你一个人在家里搬东西。左手从门口拿进来放桌上(写内存),右手再从桌上拿到后门口递出去(读内存)。一个人两手交替,速度可想而知。
4.2 总线交换(Switching via Bus)#
输入端口把包放到一条共享总线上,输出端口从总线上取走。
1 | 输入端口0 ──┐ |
优点:比内存交换快,不需要 CPU 介入。
缺点:总线是共享的!同一时刻只能有一个端口往总线上放数据。如果 N 个输入端口同时有包要送,只有一个能成功,其他要等。总线带宽成了瓶颈。
🎯 生活类比:公司只有一部电梯。每层楼的人都要用它下楼。同一时间只能载一批人,大家只能排队等。楼层多了就堵成一锅粥。
大多数家用路由器(包括 OpenWrt 设备)用的就是总线交换架构。因为家用场景流量不大,总线够用了。但在骨干网,总线交换就力不从心了。
4.3 互联网络交换(Switching via Interconnection Network)#
这是高性能路由器用的方案。用一个多级的交叉开关矩阵(Crossbar Switch),让多个输入-输出对同时交换数据。
1 | 输出0 输出1 输出2 输出3 |
如果输入端口0要送到输出端口0,同时输入端口1要送到输出端口1,这两个交换可以同时进行,互不干扰。只有当两个输入端口要送到同一个输出端口时才会冲突。
优点:可以并行交换,吞吐量高,是现代骨干路由器的标配。
缺点:复杂、贵、功耗大。N×N 的 crossbar 需要 N² 个交叉点。
🎯 生活类比:从”一部电梯”升级到了”立交桥”。每条路都有自己的匝道,想去哪直接走对应的匝道,互不干扰。只有当两辆车想去同一个出口时,才需要排队。
4.4 交换结构的性能瓶颈#
无论哪种交换方式,当多个输入端口的包都想去同一个输出端口时,就会出现拥塞(HOL Blocking,Head-of-Line Blocking)。排在队头的包如果因为输出端口冲突而被阻塞,后面即使目的地是空闲端口的包也出不去——这就是队头阻塞问题。
想象你在超市收银台排队。你前面的大哥在找零钱(输出端口忙),你后面的小姐姐其实只是想退个货(另一个收银台空闲),但她排在你后面,只能等你——这就是队头阻塞。
五、输出端口:出门前的”排队等候区”#
5.1 输出端口的结构#
输出端口是包离开路由器前的最后一站:
1 | ┌──────────────────────────────────┐ |
5.2 为什么要排队?#
排队的根本原因:到达速率 > 输出链路的发送速率。
想象一个水槽。进水管的水流(到达的包)大于出水管的水流(输出链路带宽),水就会在槽里积攒。这就是排队。
1 | 到达的包 输出链路 |
当队列满了,新来的包就只能被丢弃(Drop)或者挤掉已有的包(如果用了 AQM 主动队列管理)。
5.3 排队场景#
考虑两种排队场景:
场景一:输入排队
当交换结构来不及处理所有输入端口的包时,包在输入端口排队。前面提到的 HOL 队头阻塞就是输入排队的主要问题。
场景二:输出排队
当多个输入端口的包同时到达同一个输出端口时(交换结构足够快,但输出链路只有一条),包在输出端口排队。
实际路由器中,输出排队更常见,因为现代 crossbar 交换结构速度已经足够快,瓶颈通常在输出链路带宽上。
5.4 队列管理策略#
队列满了怎么办?有几种策略:
① 尾丢弃(Tail Drop,FIFO/DropTail)
最简单的策略:队列满了,新来的包直接丢弃。
1 | 队列状态:[包A][包B][包C][包D][包E] ← 满了! |
缺点:会导致”全局同步”问题——TCP 流同时感知到丢包,同时降低发送速率,然后同时增大,导致网络流量呈锯齿状波动。
② 随机早期检测(RED, Random Early Detection)
在队列还没满的时候就开始以一定概率随机丢包,给 TCP 发送方”温柔”的信号:”快了快了,悠着点”。
1 | 队列长度 < min_threshold → 不丢包 |
RED 的聪明之处在于:在崩溃之前就发预警,而不是等到队列满了才暴力丢包。
🎯 生活类比:尾丢弃就像高速收费站在车已经堵了一公里后才关闭入口。RED 则是在车排队到 200 米时就放一块”前方拥堵,建议绕行”的牌子,让一部分车主动分流。
③ 公平排队(Fair Queuing)
不同流轮流发送,避免一个贪婪的流量霸占整个队列。
🎯 生活类比:银行窗口排队,每个人限办 3 分钟,时间到了下一位。不会因为前面有个大哥办 50 张银行卡的复杂业务就让你等一下午。
5.5 调度策略(Scheduling)#
当输出端口有多个包排队时,谁先走?这就是调度器要回答的问题。
| 调度策略 | 规则 | 特点 |
|---|---|---|
| FIFO(先来先服务) | 按到达顺序发送 | 最简单,但无法区分优先级 |
| 优先级排队 | 高优先级先发 | 可能导致低优先级饿死 |
| 加权公平排队(WFQ) | 按权重分配带宽 | 各流公平,可保证最低带宽 |
| 缺口轮转(Round Robin) | 轮流给每个流发送机会 | 简单的公平 |
🔧 实战关联:OpenWrt 的 SQM(Smart Queue Management)就是一个典型的输出端口队列管理 + 调度系统。当你在家开 Zoom 会议的同时下载大文件,SQM 通过 CAKE 或 fq_codel 算法,保证 Zoom 的包(低延迟需求)优先发送,而下载流量(吞吐量需求)排队等候。这背后就是今天讲的排队管理和调度策略!
六、把所有部件串起来:一个包的路由器之旅#
让我们追踪一个 IP 数据包穿过路由器的完整过程:
1 | 1. 包从物理链路到达输入端口 X |
🎯 完整类比:想象你是一封信。
- 邮递员把你从信箱里取出来(物理层接收)
- 分拣员检查信封上的地址(链路层解封装 + 网络层查表)
- 分拣员决定你该发往哪个城市的分拣中心(最长前缀匹配 → 输出端口)
- 你被放到传送带上,送到了正确的发货口(交换结构)
- 发货口前面排了很多信,你在队列里等了一会儿(输出排队)
- 终于轮到你了,你被装到邮车里出发了(调度发送)
- 到了下一个分拣中心,重复以上过程……
一封从北京寄到上海的信,中间可能经过 5-10 个分拣中心。一个从你的电脑发到 B 站服务器的数据包,中间通常也要经过 5-15 台路由器。每经过一台路由器,就叫一跳(hop)。
七、实战分析:你家路由器的一天#
7.1 OpenWrt 路由器 = 小型路由器#
你家里的 OpenWrt 路由器就是一个麻雀虽小五脏俱全的路由器:
1 | # 查看路由表(控制平面的产物) |
- 输入端口:WAN 口(eth0)和 LAN 口(br-lan,其实是一个 bridge)
- 交换结构:多数用总线交换(SoC 集成)
- 输出端口:同上,WAN/LAN 口复用
- 路由处理器:路由器的 CPU(可能就是一个小小的 ARM 核)
- 转发表:
ip route看到的路由表
7.2 frp 数据转发的路由过程#
当你用 frp 做内网穿透时,数据包经过了哪些路由器?
1 | 你的服务器(内网 192.168.1.100) |
每一跳,路由器都在做同样的事:
- 收到包,看目的 IP
- 最长前缀匹配,决定下一跳
- 通过交换结构送到对应端口
- 从输出端口发出去
frp 服务器收到包后,解封装,看到的是你内网服务的应用层数据(比如 HTTP 请求),然后再转发给目标服务。从网络层的角度,frp 服务器只是路径上的一个中间节点,但它同时也是一个应用层代理——既走路由器的活(网络层转发,不过是通过应用层代理实现的),又做应用层的事。
💡 有趣观察:frp 本质上是在应用层模拟了网络层的转发功能。真正的路由器在 IP 层转发,而 frp 在 TCP/应用层转发。这就像快递公司(IP 路由)和跑腿小哥(frp 代理)都能帮你送东西,但快递公司走的是自动化分拣流水线,跑腿小哥走的是”人肉转交”——速度和效率不可同日耳语,但跑腿小哥能送的”东西”更灵活。
八、路由器的性能指标#
8.1 吞吐量#
路由器的吞吐量是指单位时间内能处理的数据量。这取决于三个环节中最慢的那个:
- 输入端口处理速度
- 交换结构带宽
- 输出端口发送速度
木桶效应——哪个环节最慢,整个路由器的吞吐量就被限制在哪里。
8.2 延迟#
一个包穿过路由器的时间包括:
- 处理延迟:查表、检查首部(通常微秒级)
- 排队延迟:在输出队列等待的时间(取决于拥塞程度,从 0 到毫秒级不等)
- 交换延迟:通过交换结构的时间(通常纳秒级)
注意,路由器的延迟主要来自排队。如果你家的网速测试显示延迟很高,很多时候不是路由器处理慢,而是队列太长了!
8.3 丢包率#
当队列满了,包被丢弃。丢包率是衡量路由器拥塞程度的重要指标。TCP 会根据丢包调整发送速率——这就是 Day 8 讲的 TCP 拥塞控制的基础。现在你知道了:TCP 感知到的”丢包”,本质上很多时候就是路由器输出端口队列满了之后的尾丢弃(或 RED 丢弃)。
💡 恍然大悟时刻:TCP 拥塞控制和路由器排队管理其实是一个闭环系统。路由器丢包 → TCP 减速 → 路由器队列变短 → 不再丢包 → TCP 加速 → 路由器队列又变长 → 又开始丢包……如此循环。理解了这个循环,你就理解了互联网流量自我调节的核心机制。
关键知识点回顾#
让我们用一张表总结今天的内容:
| 概念 | 要点 |
|---|---|
| 网络层两大功能 | 转发(数据平面,本地快速决策)+ 路由(控制平面,全局拓扑计算) |
| 数据平面 vs 控制平面 | 数据平面硬件实现每包转发,控制平面软件实现路由协议;SDN 将二者分离 |
| 路由器四大组件 | 输入端口、交换结构、输出端口、路由处理器 |
| 输入端口核心 | 最长前缀匹配查找,决定输出端口 |
| 交换方式 | 内存交换(慢)、总线交换(中等)、互联网络/crossbar(快) |
| 输出端口核心 | 排队管理(DropTail、RED)+ 调度策略(FIFO、优先级、WFQ) |
| 排队位置 | 主要在输出端口排队(现代交换结构足够快) |
| HOL 阻塞 | 输入排队时的队头阻塞问题 |
| 队列管理策略 | 尾丢弃(简单但导致全局同步)、RED(主动预警)、公平排队 |
| TCP 与队列的闭环 | 路由器丢包 → TCP 减速 → 队列缩短 → TCP 加速 → 循环 |
一句话总结:路由器就是一个高性能的”快递分拣中心”——输入端口看地址(最长前缀匹配),交换结构搬运包裹(crossbar 并行交换),输出端口排队发货(排队管理+调度),路由处理器在后台规划路线(路由协议)。
Day 10 预告#
今天我们了解了路由器的硬件架构和工作原理,但有一个关键的东西还没深入:路由器查的那张转发表是怎么来的? 路由器怎么知道去往某个网络该走哪条路?这涉及到:
- IP 协议详解:IPv4 数据报格式、分片与重组
- IPv6:为什么需要 IPv6?IPv4 和 IPv6 有什么区别?
- DHCP:你的电脑是怎么自动获得 IP 地址的?
- NAT:你家一个公网 IP,多台设备怎么上网的?
- 路由算法:链路状态(LS)和距离矢量(DV)算法是怎么算出最短路径的?
- OSPF 与 BGP:互联网的两 大路由协议
Day 10,我们将深入 IP 协议的细节,看看那个 192.168.1.1 背后的故事。咱们不见不散!
📖 读书进度:《计算机网络:自顶向下方法》第 8 版 第 4 章(4.1-4.2 节)
下期见 👋