计算机网络之七 - OSI 与 TCP/IP 分层模型
本篇是计算机网络系列的第七篇。在前面的文章中,我们已经分别探讨了 IP、DNS、DHCP、TCP、HTTP 等具体的技术点。然而,这些技术并非孤立存在,它们是一个庞大而精密的系统中的有机组成部分。为了理解它们如何协同工作,我们需要一个宏观的框架来审视整个网络世界。这个框架,就是网络分层模型。
终于轮到分层模型了。其实在绝大多数讲计算机网络的文章中都会在一开始就介绍分层模型,但是我每次读到这种文章时,都会被其庞大的架构所阻拦 —— 它太完美,也太完整,我貌似没法一下子完全理解与接受。所以本系列文章并没有选择从分层模型入手,也有这方面的原因。
本文将作为系列的一个阶段性总结,涉及到业界最核心的两个网络模型——OSI 七层模型和 TCP/IP 模型。我们不仅将理解它们是什么,更将探讨它们为何如此设计、关键协议的内部细节、设计哲学的差异,以及它们在现实世界中的局限性,帮助你将先前学到的知识“融会贯通”,构建一个系统性的网络知识体系。
其余几篇的目录:
- 计算机网络之一 - IP 与端口
- 计算机网络之二 - URL 与 DNS
- 计算机网络之三 - DHCP 与内网穿透
- 计算机网络之四 - 虚拟网卡与 WireGuard
- 计算机网络之五 - HTTP 与 HTTPS
- 计算机网络之六 - 可靠的 TCP 与高效的 UDP
为什么需要网络分层
在深入模型细节之前,我们首先要回答一个根本问题:为什么网络通信需要“分层”?
想象一个极其复杂的跨国寄送包裹的流程。如果我们将整个流程视为一个单一的、巨大的任务,那么任何一个环节的微小变动(例如更换了运送卡车),都可能需要重新设计整个系统,这无疑是低效且脆弱的。
一个更合理的设计是将其模块化,即分层。每一层都只关心自己的任务,并为上一层提供服务,同时使用下一层提供的服务。这种设计带来了几个显而易见的好处:
- 简化问题:将一个复杂的大问题分解为多个简单的小问题。
- 标准化:每一层都可以建立统一的标准(如 RFC),只要接口不变,任何一方的内部实现变化都不会影响其他层。
- 解耦合:不同层的技术可以独立发展和演进。例如,我们可以将物理传输从电缆升级到光纤,而无需改变上层的网页浏览体验。
- 易于教学和排错:当网络出现问题时,我们可以逐层排查,极大地提高了故障定位的效率。
当然,分层也并非没有代价,例如数据在各层之间传递会带来一定的性能开销。但在绝大多数场景下,其带来的结构性优势远大于性能上的微小损失。
OSI 七层参考模型:理论的丰碑
OSI 模型(Open Systems Interconnection model) 是由国际标准化组织(ISO)提出的一个概念模型,旨在为计算机网络提供一个标准的、通用的体系架构。它被誉为理论上最完整、最严谨的网络模型,虽然在商业上并未取得绝对的成功,但它对于理解网络通信的各个环节具有极高的指导价值。
OSI 模型将网络通信精确地划分为了七个层次。下面我们自顶向下逐层解析其功能与核心协议。
-
第七层:应用层 (Application Layer)
这是用户最直接接触的一层,负责为应用程序提供网络服务。它定义了应用程序之间如何交换和解释数据。正如我们在 《计算机网络之五 - HTTP 与 HTTPS》 中探讨的 HTTP 协议,就工作在这一层。 -
第六层:表示层 (Presentation Layer)
表示层主要处理数据的格式化、加密和压缩,确保一个系统的应用层所发送的数据能被另一个系统的应用层正确理解。它如同一个“翻译官”。 -
第五层:会话层 (Session Layer)
这一层负责建立、管理和终止不同设备间的会话(Session)。 -
第四层:传输层 (Transport Layer)
传输层为两个主机之间提供端到端(end-to-end)的数据传输服务。其协议数据单元(PDU)称为数据段 (Segment)。 -
第三层:网络层 (Network Layer)
网络层负责在复杂的网络环境中,为数据包选择最佳的路由路径,实现逻辑地址(IP 地址)的寻址。其 PDU 称为数据包 (Packet)。 -
第二层:数据链路层 (Data Link Layer)
数据链路层负责在相邻的两个网络节点之间传输数据帧。它处理物理地址(MAC 地址)的寻址。其 PDU 称为数据帧 (Frame)。 -
第一层:物理层 (Physical Layer)
这是模型的最底层,负责传输原始的二进制比特流(0和1)。其 PDU 称为比特 (Bit)。
TCP/IP 模型:实践的胜利者
与 OSI 的理论性不同,TCP/IP 模型是伴随着互联网的实践发展而来的,是当前事实上的工业标准。在深入其结构之前,我们先回答一个问题:它为什么叫 “TCP/IP” 模型?
名字的由来
这个模型得名于其体系中的两个最核心、最基础的协议:
- TCP (传输控制协议):工作在传输层,提供可靠的、面向连接的数据传输服务。它如同网络通信的“质量总监”。
- IP (网际协议):工作在网络层,负责数据包的寻址和路由。它如同网络通信的“全球邮政系统”。
TCP 和 IP 的重要性如此之高,以至于它们成为了整个协议族(Protocol Suite)的代名词。因此,描述这个协议族架构的模型,也就自然而然地被称为 “TCP/IP 模型”。
分层结构
TCP/IP 模型更加简洁和实用,通常被描述为四层或五层模型。
TCP/IP 四层模型
这是最经典的 TCP/IP 模型划分,它将功能相近的几个层进行了合并,更侧重于描述协议簇的宏观结构:
- 应用层 (Application Layer):对应 OSI 的应用层、表示层、会话层。包含了所有高层协议,如 HTTP, FTP, DNS 等。
- 传输层 (Transport Layer):对应 OSI 的传输层。负责端到端的通信,核心是 TCP 和 UDP 协议。
- 网际层 (Internet Layer):对应 OSI 的网络层。核心是 IP 协议,负责数据包的寻址和路由。
- 网络接口层 (Network Interface Layer):对应 OSI 的数据链路层和物理层。负责处理与物理网络媒介(如以太网、Wi-Fi)相关的所有事务。
TCP/IP 五层模型
为了教学和理解上的便利,业界更常使用一个五层模型。它实际上是 OSI 和 TCP/IP 四层模型的一个折中,将四层模型中的“网络接口层”重新拆分为“数据链路层”和“物理层”,从而能更清晰地描述底层的工作原理。这个五层模型也是我们后续文章将主要参照的结构。
- 应用层 (Application Layer):同四层模型,对应 OSI 的上三层。
- 传输层 (Transport Layer):同四层模型,对应 OSI 的传输层。
- 网络层 (Network Layer):同四层模型的网际层,对应 OSI 的网络层。
- 数据链路层 (Data Link Layer):对应 OSI 的数据链路层。
- 物理层 (Physical Layer):对应 OSI 的物理层。
下面的表格清晰地展示了三者之间的映射关系:
OSI 七层参考模型 | TCP/IP 五层模型 | TCP/IP 四层模型 |
---|---|---|
应用层 | 应用层 | 应用层 |
表示层 | ||
会话层 | ||
传输层 | 传输层 | 传输层 |
网络层 | 网络层 | 网际层 |
数据链路层 | 数据链路层 | 网络接口层 |
物理层 | 物理层 |
核心协议深度剖析
理解了分层,我们还需要深入协议的内部,看看它们是如何通过精巧的设计来完成各自使命的。
网络层核心:IPv4 头部结构
我们在 《计算机网络之一 - IP 与端口》 中已经初步认识了 IP 协议,它是整个网络层的核心。为了更深入地理解数据包是如何被路由的,我们有必要详细剖析其头部结构:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL |Type of Service| Total Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Identification |Flags| Fragment Offset |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Time to Live | Protocol | Header Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Destination Address |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- 版本 (Version):4位,指明协议版本,对 IPv4 来说就是 4。
- 首部长度 (IHL):4位,表示 IP 头部有多少个 32 位字(4字节)。由于该字段最大值为 15,所以 IP 头部最长为
15 * 4 = 60
字节。 - 服务类型 (Type of Service):8位,用于指定数据包的服务质量(QoS),例如低延迟、高吞吐量或高可靠性。现在通常被定义为 DSCP(差分服务代码点)。
- 总长度 (Total Length):16位,指明整个 IP 数据包(头部+数据)的总长度,单位是字节。最大长度为 65535 字节。
- 标识 (Identification)、标志 (Flags) 和 片偏移 (Fragment Offset):这三个字段共同用于 IP 分片。当一个数据包的大小超过了链路的最大传输单元(MTU)时,它必须被分割成多个小的数据包(分片)。
标识
:16位,唯一标识一个原始数据包。同一原始数据包的所有分片都具有相同的标识号。标志
:3位。第一位保留;第二位是DF
(Don't Fragment),如果置 1,表示禁止分片;第三位是MF
(More Fragments),如果置 1,表示后面还有更多分片,如果是最后一个分片则为 0。片偏移
:13位,指明当前分片的数据部分在原始数据包中的位置。
- 生存时间 (Time to Live, TTL):8位,数据包在网络中的“寿命”。每经过一个路由器,TTL 值减 1。当 TTL 变为 0 时,数据包被丢弃。这有效防止了数据包在网络中因路由错误而无限循环。
- 协议 (Protocol):8位,指明该数据包承载的上层协议是什么。例如,
6
代表 TCP,17
代表 UDP。接收方据此决定将数据交给哪个上层模块处理。 - 首部校验和 (Header Checksum):16位,用于检验 IP 头部的完整性,不包含数据部分。由于 TTL 在每一跳都会改变,所以路由器需要重新计算校验和。
- 源地址/目标地址 (Source/Destination Address):各 32 位,标识了数据包的发送方和接收方。
- 选项 (Options) 和 填充 (Padding):选项是可变长的,用于一些特殊处理,如记录路由。填充用于确保整个 IP 头部是 32 位的整数倍。
传输层核心:TCP 与 UDP
传输层负责端到端的通信,其两大核心协议 TCP 和 UDP,我们已在之前的文章中做了详细的探讨。
TCP 通过序列号、确认号、标志位等头部关键字段,以及三次握手和四次挥手等严谨的连接管理机制,提供了可靠的、面向连接的服务。关于这些内部工作细节,强烈建议您回顾 《计算机网络之六 - 可靠的 TCP 与高效的 UDP》,本文不再赘述。
网络层的路由协议
IP 协议只负责数据包的投递,但如何确定投递路径,则是由路由协议决定的。路由协议在路由器之间运行,共同构建和维护路由表。它们主要分为两大流派:
- 距离矢量协议 (Distance-Vector):如
RIP
。每个路由器只知道与它直接相邻的邻居,并与它们交换整个路由表。它关心的是“到某个目的地有多远(距离)”和“应该从哪个方向(矢量)走”。这种方式简单,但容易产生路由环路且收敛慢。 - 链路状态协议 (Link-State):如
OSPF
。每个路由器都拥有整个网络的拓扑图。当网络状态变化时,路由器会向所有其他路由器广播这个变化。它关心的是“整个网络的连接状态”。这种方式更复杂,但收敛快且不易产生环路。
OSI 与 TCP/IP:一场理论与实践的赛跑
一个经典问题是:为什么理论上更完美的 OSI 模型,在实践中却输给了更“粗糙”的 TCP/IP 模型?
-
时机决定一切:TCP/IP 诞生于 20 世纪 70 年代,与美国国防部的 ARPANET 项目紧密结合,经过了长期的实践检验。当 OSI 模型在 80 年代后期完成其标准化工作时,TCP/IP 早已在学术界和军事领域广泛部署,形成了强大的事实标准。
-
哲学差异:OSI 遵循“先制定标准,再进行实现”的学院派哲学,力求大而全,导致其过于复杂。而 TCP/IP 则源于“先有可用实现,再提炼标准”的工程师哲学,更注重解决实际问题,因此更简洁、高效。
-
实现复杂度:OSI 模型的复杂性(尤其是会话层和表示层)使得其实现难度和运行开销都很大。相比之下,TCP/IP 将这些功能交由应用层自行处理,大大降低了核心网络的复杂度。
最终,这场赛跑以实践派的胜利告终。OSI 虽然输掉了市场,但它清晰的层次划分和严谨的定义,使其成为了网络教育和理论分析不可或缺的“教科书”。
应用模型:从理论到实践
理解了分层模型这一“地图”,我们便拥有了分析和诊断网络问题的框架。接下来,我们将通过两个具体的案例,将这些抽象的层次和协议应用到实际场景中。第一个案例将展示一次标准网络请求的完整流程,第二个案例则将剖析一个常见的开发陷阱,以展示分层模型在排错中的指导价值。
案例一:一次完整的 HTTP 请求
这个案例将追踪一次典型的、访问外部网站的 HTTP 请求,以展示数据包如何穿越互联网。
场景设定:
- 你的电脑:IP
192.168.1.100
(此地址通常通过 DHCP 服务动态获取,相关细节请回顾 《计算机网络之三 - DHCP 与内网穿透》), MACAA:AA:AA:AA:AA:AA
- 家庭路由器:内网 IP
192.168.1.1
, MACBB:BB:BB:BB:BB:BB
;公网 IP123.123.123.123
- 目标网站服务器:IP
216.58.200.46
, MACCC:CC:CC:CC:CC:CC
旅程开始:
-
DNS 查询:在一切开始之前,浏览器需要知道
example.com
的 IP 地址。它会向 DNS 服务器发起查询,将域名解析为 IP 地址216.58.200.46
。关于 DNS 的详细工作原理,请参阅 《计算机网络之二 - URL 与 DNS》。 -
应用层:你在浏览器输入
http://example.com
。浏览器构建一个 HTTP GET 请求报文。 -
传输层:操作系统为该请求分配一个临时的源端口(如
54321
),目标端口为 HTTP 的标准端口80
。然后,它将 HTTP 报文封装进一个 TCP 数据段,并写入 TCP 头部(包含源/目标端口等信息)。 -
网络层:操作系统继续封装,添加 IP 头部,形成 IP 数据包。头部信息包括源 IP (
192.168.1.100
) 和目标 IP (216.58.200.46
)。 -
数据链路层 (第一跳:电脑 -> 路由器):
- 操作系统查询路由表,发现目标 IP
216.58.200.46
不在本地网络,需发往默认网关 (192.168.1.1
)。 - 操作系统使用 ARP 协议查询
192.168.1.1
对应的 MAC 地址,得到路由器的 MACBB:BB:BB:BB:BB:BB
。 - 最终,它构建一个以太网帧,头部包含源 MAC (
AA:AA...
) 和目标 MAC (BB:BB...
),并将 IP 数据包作为其“货物”。
- 操作系统查询路由表,发现目标 IP
-
物理层:电脑网卡将该数据帧转换为电信号,通过网线发送出去。
-
在路由器上 (关键中转):
- 路由器的数据链路层接收到数据帧,检查目标 MAC 是自己,于是“拆开”帧,取出 IP 数据包,并将其向上传递到网络层。
- 路由器的网络层执行 NAT (网络地址转换)。它将 IP 包的源 IP 从
192.168.1.100
修改为自己的公网 IP123.123.123.123
,并记录下这个映射关系,以便响应回来时能正确转发。 - 路由器准备将修改后的 IP 包发往互联网。它查询自己的路由表,找到下一跳的地址,并构建一个新的数据链路层帧(此时的目标 MAC 将是下一个路由器的 MAC),然后发送出去。
-
在互联网中:数据包经过多个路由器的多次转发,每一跳都重复着“解封装-查路由-再封装”的过程,但 IP 头部的源/目标 IP 始终不变(除了 NAT 网关)。
-
抵达服务器:服务器接收到数据,自底向上进行解封装,最终将 HTTP 请求报文送达 Web 服务器应用。服务器处理请求后,再以同样的方式将响应数据封装并发回。
案例二:从 localhost
到局域网的连接问题
本博客基于 Gridea 实现,该客户端提供了一个便捷的“预览”功能,点击后会在浏览器中打开 http://localhost:4000
这样的地址,用于实时查看文章效果。这个过程在本地电脑上运行良好,但当作者希望使用其他设备(如手机)预览地址文章时就显得力不从心了,因为这个地址在其他设备上是 “打不开” 的。
问题的演进
-
初次尝试:一个直接的想法是在手机浏览器中输入
http://localhost:4000
。这个尝试必然会失败。其原因是localhost
是一个特殊的环回地址,它指向设备自身。手机访问localhost
,访问的是手机自己,而非提供服务的电脑。 -
二次尝试:在理解了
localhost
的局限性后,基于咱们已经学习过的计算机网络知识,下一步自然是尝试使用电脑的局域网 IP 地址。在 macOS 上我们可以通过 “设置 -> 网络” 查到电脑的 IP,假设为192.168.1.100
,于是在手机上访问http://192.168.1.100:4000
。然而,这种尝试也会失败,浏览器会显示连接超时或无法访问。
这就引出了问题的核心:在网络层面上,数据包已经能够从手机路由到目标主机,为什么连接依然无法建立?这表明问题很可能出在更高层,即运行在主机上的服务程序本身。
-
验证网络层 (Layer 3) 及以下是否通畅
在怀疑上层应用问题之前,我们必须百分之百确认基础网络是连通的。ping
命令是验证网络层连通性的最佳工具,它使用 ICMP 协议工作。我们可以在 iPhone 上安装任意一款网络调试工具(比如 iNetTools)然后执行:ping 192.168.1.100
如果
ping
成功收到回复,我们将获得一条至关重要的信息:从手机到电脑的 网络层及以下的物理层、数据链路层是完全通畅的。数据包确实已经成功抵达了目标主机的网络协议栈。这就允许我们排除掉所有底层网络问题(如 Wi-Fi 隔离、IP 冲突、子网错误等),将注意力集中到更高层次。 -
聚焦传输层 (Layer 4) 的可能性
既然网络路径没有问题,数据包在传输层“消失”的可能性就大大增加。在这一层,主要有两个实体在工作:操作系统内核(防火墙) 和 应用程序本身。- 可能性 A:被防火墙拦截。电脑的防火墙可能设定了规则,允许 ICMP 包(
ping
)通过,但阻止了针对4000
端口的 TCP 连接请求。这是一个非常合理的怀疑点。 - 可能性 B:端口上没有服务在监听。应用程序在启动时,需要向操作系统内核申请监听一个或多个具体的“地址-端口”对。如果程序只申请监听
127.0.0.1:4000
,那么当一个目标地址是192.168.1.100:4000
的数据包到达时,内核会发现没有任何程序在等待这个数据包,于是只能将其丢弃。
- 可能性 A:被防火墙拦截。电脑的防火墙可能设定了规则,允许 ICMP 包(
-
使用工具做出最终裁定
现在,我们需要一个工具来区分到底是可能性 A 还是 B。lsof
命令的作用正在于此,它能直接查询操作系统内核,告诉我们“哪个进程正在监听哪个地址的哪个端口”,从而绕过所有猜测。lsof -i :4000
其输出结果:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME Gridea 13682 rakuyo 50u IPv4 0x7e41bc65e0e51533 0t0 TCP localhost:terabase (LISTEN)
这个结果明确地告诉我们,
Gridea
进程监听的地址是localhost
。这直接证实了可能性 B。数据包并非被防火墙拦截,而是在到达内核后,因找不到对应的监听程序而被丢弃。至此,问题根源被精准定位。
解决方案
诊断出根源后,解决方案便是在服务层面进行修正。但是很可惜的是 Gridea 并没有提供修改的选项。否则我们可以将默认的 localhost
或 127.0.0.1
修改为 0.0.0.0
,实现监听地址的修改。
0.0.0.0
是一个特殊的地址,它指示操作系统监听本机所有可用的网络接口,包括环回地址和所有局域网地址。
这个排查过程清晰地展示了分层模型在解决实际问题时的指导作用。若不理解网络层的地址和监听机制,开发者可能会陷入反复检查防火墙、网络设置的无效循环中。而通过运用正确的理论知识和诊断工具,则可以快速、精准地定位问题根源。
分层视角下的网络安全
分层模型也为我们理解和应对网络安全问题提供了一个清晰的框架。攻击可能发生在任何一层:
- 数据链路层安全:攻击者在局域网内,可以通过 ARP 欺骗来冒充网关,窃听或篡改流量;或者通过 MAC 泛洪攻击耗尽交换机的 MAC 地址表,使其变为“集线器”,从而嗅探整个网络的流量。
- 网络层安全:攻击者可以伪造源 IP 地址(IP 欺骗)来隐藏身份或嫁祸他人。经典的 DDoS 攻击(如 SYN Flood)也利用了 IP 层的机制,发送大量伪造源 IP 的连接请求,耗尽服务器资源。
- 传输层安全:端口扫描是黑客探测目标主机开放服务的主要手段,它直接作用于传输层的端口。
- 应用层安全:这是最广为人知的攻击面,包括 SQL 注入、跨站脚本(XSS)、CSRF 等,它们都利用了应用程序自身的逻辑漏洞。
为了应对这些威胁,安全协议也作用于不同层面。例如,IPsec 工作在网络层,提供端到端的加密和认证。而我们熟知的 TLS/SSL 则比较特殊,它逻辑上位于应用层和传输层之间,为上层的应用数据提供加密、完整性保护和身份认证。此外,另一种强大的安全工具是 VPN(虚拟专用网络)。技术如 WireGuard 通过创建一张虚拟网卡,并在网络层对所有数据进行加密封装,形成一个安全的“隧道”。所有进出你设备的流量都通过这个隧道传输,从而有效地保护了通信的私密性和完整性,抵御了中间人攻击。更深入的探讨可以参见 《计算机网络之四 - 虚拟网卡与 WireGuard》。
模型的局限性与争议
分层模型是完美的吗?并非如此。在学术和工程实践中,它们也存在一些争议:
- 归属争议:有些重要协议难以被完美地归入某一层。例如,ARP 协议通过 IP 地址查询 MAC 地址,它似乎横跨了网络层和数据链路层。ICMP 协议(
ping
命令所使用的协议)被 IP 协议承载,但它本身是为网络层提供控制和错误信息的,其位置也存在争议。 - 效率问题:严格的分层会带来性能开销。在一些高性能计算场景中,为了追求极致的低延迟,可能会出现“跨层”操作,绕过某些协议栈以加速数据处理。
- 模型与现实的脱节:OSI 模型的会话层和表示层在现实中很少被独立实现,它们的功能往往被应用层自身所包含,这也是 TCP/IP 模型将其合并的原因。
理解这些局限性,能帮助我们更辩证地看待这些模型,认识到它们是用于理解复杂系统的强大工具,而非一成不变的教条。
总结
通过本文的深度剖析,我们不仅了解了 OSI 和 TCP/IP 模型是什么,更探讨了它们的设计哲学、历史演进、协议细节、实践流程乃至理论局限。
网络分层模型,本质上是一种“分而治之”的工程智慧。它将一个不可能完成的复杂任务,拆解为一系列定义清晰、可以管理的子任务。理解这些分层模型,就像是拿到了一张高精度的网络世界地图。当我们再去审视之前文章中讨论的 HTTP、TCP、IP、DHCP 等协议时,便能清晰地知道它们在整个通信流程中所处的位置和扮演的角色。有了这个“世界观”,我们后续探索更复杂的网络技术时,才能做到胸有成竹,游刃有余。