§ 2.1 · Section

OSI 七层模型

Open Systems Interconnection Model

OSI 七层模型是 1984 年国际标准化组织(ISO)提出的"理想分层"——把网络通信拆成 7 个层次,每层只管一件事。虽然互联网实际用的是 TCP/IP 四层,但 OSI 是理解分层的最佳教材。

生活场景
📮 寄一封国际挂号信

你从北京寄一封挂号信到纽约——整个过程可以拆成 7 步:

① 你写信(内容)
② 你装信封,写地址(格式)
③ 你去邮局,填国际快递单(协议)
④ 邮局分拣,决定走空运还是海运(路由)
⑤ 飞机/船运输到美国(传输)
⑥ 美国邮局分拣,送到收件人楼下(链路)
⑦ 邮递员敲门,收件人签收(物理送达)

每一步都有专人负责,换其中一步不影响其他步。OSI 七层就是把这个思路应用到网络。

OSI 的来路:一场标准之战的前夜

要理解 OSI 为什么长成七层这个样子,得先回到 1977 年。那时候计算机网络刚刚起步,市场上是一片互不兼容的私有网络:IBM 有 SNA(System Network Architecture,1974 年发布),DEC 有 DECnet,Xerox 有 XNS,霍尼韦尔有自己的一套。买了 IBM 的机器就只能连 IBM 的机器,换个厂商等于整个网络推倒重来。这种"厂商锁定"在当时是行业常态,也是所有采购方的噩梦。

"互不兼容的私有网络"听着抽象,换成大白话就是:那时候买设备就像买一整套只认自家插头的电器——IBM 的插头只能插 IBM 的插座,DEC 的插头插不进去。你想换个牌子,得把家里所有插座全砸掉重装。今天你随便买哪家的路由器都能连上网,这件事在 1977 年是做不到的。

于是国际标准化组织(ISO)在 1977 年成立了 SC16 分委员会,目标是造一个厂商中立的开放互联参考模型——名字里的"Open Systems"(开放系统)四个字就是冲着 IBM SNA 的封闭去的。1978 年出了初稿,1980 年发布草案,1984 年正式成为国际标准 ISO 7498(后来与国际电报电话咨询委员会 CCITT 的 X.200 建议书对齐,所以你也会看到"ITU-T X.200"这个编号)。主要设计者是英国人 Hubert Zimmermann 和 Charles Bachman——后者是 1973 年图灵奖得主,数据库领域的大牛。

有意思的是,OSI 的分层灵感一部分来自 Bachman 在数据库领域的分层抽象经验,一部分来自 IBM SNA 已有的七层结构(SNA 也是七层,但层的划分不同)。换句话说,OSI 是"用 IBM 的方法论去打破 IBM 的垄断"。这套模型在学术和政府采购领域一度势不可挡:1990 年美国政府发布 GOSIP(Government OSI Profile),一度强制要求联邦机构采购的网络设备必须支持 OSI 协议栈。

那句"用 IBM 的方法论去打破 IBM 的垄断"特别有意思,打个比方就是:大家嫌某家餐厅的菜单太霸道,于是照着它的菜单结构,重新编了一份谁都能用的公版菜单。结构学它的,但从此谁都能照着做菜——这就是"Open"这个词在当年的分量。

七层模型总览

层数名称干什么类比代表协议/设备
7应用层 · Application用户直接用的服务信的内容HTTP、FTP、SMTP、DNS
6表示层 · Presentation数据格式转换、加密翻译官(中文→英文)SSL/TLS、JPEG、ASCII
5会话层 · Session建立、管理、断开会话电话接线员NetBIOS、RPC
4传输层 · Transport端到端可靠传输挂号信 vs 平信TCP、UDP
3网络层 · Network选路、寻址分拣中心IP、ICMP、路由器
2数据链路层 · Data Link相邻节点可靠传输邮递员Ethernet、WiFi、交换机
1物理层 · Physical比特流传输马路/飞机/船网线、光纤、无线电

这张表看着密,用寄一件国际快递串一遍就全通了:应用层=你要送的那件礼物本身;表示层=把说明书翻译成对方看得懂的语言、再拿真空袋压一压(编码、压缩、加密);会话层=跟对方约好"我这两天寄,你记得在家";传输层=选普通件还是要签收的挂号件;网络层=面单上写清寄往哪个国家哪座城市;链路层=每一段路交给具体哪辆车、哪个网点;物理层=真正拉货的那条路、那架飞机、那条船。七层不是七个部门,是同一件事上七件性质完全不同的活儿。

先记住每层的"数据单元"和"寻址方式"

上面那张总览表是给你建立整体印象的。但真正读文档、看抓包、跟同行交流时,你需要的是另外三样东西:每层数据块的正式名字(PDU)、每层用什么地址找人、每层的头部大概多大。这三样是"网络人的行话",记住它们比背层名有用得多。

PDU 名称寻址方式典型头部大小头部里最关键的字段
7 应用层数据 / 报文 MessageURL、域名不定(HTTP 头常 200~800 B)Host、Content-Length
6 表示层数据 DataTLS 记录头 5 B内容类型、版本、长度
5 会话层数据 Data会话 ID视协议而定会话标识、同步点
4 传输层段 Segment(TCP)/ 数据报 Datagram(UDP)端口号(16 位,0~65535)TCP 20~60 B,UDP 固定 8 B源/目的端口、序号、窗口
3 网络层分组 / 包 PacketIP 地址(IPv4 32 位 / IPv6 128 位)IPv4 20~60 B,IPv6 固定 40 B源/目的 IP、TTL、协议号
2 数据链路层帧 FrameMAC 地址(48 位)以太网 14 B + 4 B CRC目的 MAC、源 MAC、类型
1 物理层比特 Bit / 符号 Symbol无地址概念前导码 8 B(不算头部)时钟同步、电平定义

这张表里藏着一条极重要的规律:越往下走,地址越"本地";越往上走,地址越"全局"。MAC 地址只在同一个局域网里有意义,出了这个网段就没人认;IP 地址在全球范围内有意义,任何一台路由器都能拿它查表;端口号则完全是"主机内部"的概念,用来区分同一台机器上的不同程序。三种地址各管一段,缺一不可——这也是为什么发一个包需要同时知道对方的 IP(去哪个城市)和下一跳的 MAC(交给谁转发)。

"越往下越本地、越往上越全局"这条规律,打个比方就是地址的三种粒度:MAC 好比"这栋楼三层左手第二扇门上的那块名牌"(出了这栋楼没人认);IP 好比"某市某区某路 5 号院"(全国的快递系统都认);端口好比"501 室里的哪张办公桌"(只在这个屋里有意义)。三个都得有,因为它们回答的是三个不同的问题:哪座城市、哪扇门、屋里哪张桌。

第一层 · 物理层(Physical)

最底层——只管"怎么把 0 和 1 变成电信号/光信号/无线电波发出去"

说白了,物理层就是那条路本身——柏油马路、铁轨、航线。它压根不关心车上装的是家具还是水果,只管"这条路能不能跑车、一次能跑多快、最长能跑多远"。这也是七层里唯一真的碰到物质世界的一层:其余六层全是软件里的约定,只有这一层是真的电压、真的玻璃纤维、真的电磁波。

物理层是唯一"真的碰到物质世界"的一层,所以它的规范里全是电气工程师的语言:电压是多少伏、阻抗多少欧、接口有几根针、时钟频率多少赫兹、编码用曼彻斯特还是 4B/5B。举几个你可能见过的具体数字:标准以太网双绞线(Cat5e)最长 100 米——超过这个距离信号衰减到无法识别;单模光纤可以跑几十公里;千兆以太网(1000BASE-T)用四对铜线同时双向传输,每对线上跑 250 Mbps。

物理层还负责一件容易被忽视的事:把比特"编码"成信号。你不能简单地"高电平=1、低电平=0",因为如果连续传 100 个 0,接收方的时钟会漂移,数不清到底过了几个比特。所以真实的编码方案都带有"自同步"能力:曼彻斯特编码在每个比特中间强制跳变一次,4B/5B 编码把 4 位数据映射成 5 位码字以保证不会出现太长的连续同值。这些细节和上层协议完全无关——TCP 永远不知道自己的字节最终是以什么波形跑在光纤里的。

那个"连续传 100 个 0 会数不清"的问题,通俗地说就是传送带上运一批一模一样的白箱子,中间没有任何标记,你就数不清到底过去了多少个。所以真实的编码方案都会人为在每个箱子中间刻一道印子(曼彻斯特编码),或者规定"每四个箱子必须掺一个花色的"(4B/5B)——目的不是传信息,纯粹是为了让对面能数得清。

物理层标准年份速率介质与最大距离
10BASE-T199010 Mbps双绞线 100 m
100BASE-TX(百兆)1995100 MbpsCat5 双绞线 100 m
1000BASE-T(千兆)19991 GbpsCat5e 双绞线 100 m
10GBASE-T(万兆)200610 GbpsCat6a 双绞线 100 m
1000BASE-LX(单模光)19981 Gbps单模光纤 5~10 km
802.11ax(WiFi 6)2021理论 9.6 Gbps2.4/5 GHz 无线电,室内数十米

集线器(Hub)是纯正的物理层设备,它的工作方式简单到粗暴:从任何一个口收到信号,就往其他所有口原样广播出去,完全不看内容。这意味着接在同一个 Hub 上的所有机器共享带宽、且随时可能"同时说话"造成冲突(这就是 CSMA/CD 碰撞检测存在的原因)。1990 年代末交换机价格下来后,Hub 就彻底退出历史舞台了——今天你几乎不可能买到一台新的 Hub。

集线器干的活儿说白了就是小区里那个大喇叭:不管你想跟谁说话,它一律全院广播,剩下的靠各家自己判断"这句是不是叫我"。后果是一次只能有一个人说话,两个人同时开口就全听不清了(这就是碰撞)。后来交换机便宜了,相当于每家装了直通电话,大喇叭自然就退休了。

第二层 · 数据链路层(Data Link)

管"怎么在相邻两台设备之间可靠地传数据"——比如你的电脑和路由器之间。

链路层干的活儿相当于快递的最后一公里派送员:他只管"从这个网点送到那栋楼",压根不管这件货最终是要飞去德国还是留在本市。"相邻"这两个字是它的全部边界——它眼里的世界就只有隔壁那一台设备。

链路层做的第一件事是成帧(Framing)——在无边界的比特流上划出"一个包从哪里开始、到哪里结束"。以太网帧的结构固定得像一张表单,我们把它按字节摊开看:

以太网 II 帧格式(IEEE 802.3):

+----------+--------+--------+--------+-------------------+--------+
| 前导码   | 目的MAC| 源MAC  | 类型   | 数据(载荷)      | FCS    |
| 8 字节   | 6 字节 | 6 字节 | 2 字节 | 46 ~ 1500 字节    | 4 字节 |
+----------+--------+--------+--------+-------------------+--------+
                    ↑ 14 字节头部 ↑                        ↑ CRC32 ↑

类型字段(EtherType)的常见取值:
  0x0800 = 上层是 IPv4
  0x0806 = 上层是 ARP
  0x86DD = 上层是 IPv6
  0x8100 = 带 VLAN 标签(802.1Q,会再插 4 字节)

一个完整以太网帧最小 64 字节、最大 1518 字节(不含前导码)
所以载荷最大 1500 字节 —— 这就是著名的 MTU = 1500

那个 MTU(Maximum Transmission Unit)= 1500 是整个互联网最重要的魔法数字之一。它是 1980 年 DIX 以太网规范拍下来的,理由是当年的内存很贵、且要限制单台机器占用共享总线的时间。四十多年过去,链路速率涨了一万倍,这个 1500 却几乎没变——因为全世界的设备、防火墙、隧道都默认了它。数据中心内部为了提升吞吐会启用"巨型帧"(Jumbo Frame,MTU 9000),但一旦要过公网就必须回到 1500。

1500 这个数字换算一下就好记了:1500 字节大约是 750 个汉字,也就是半页 A4 纸的量。所以 MTU 说白了就是快递公司规定的"单个纸箱最大尺寸"——半页 A4 纸那么多内容,一箱刚好装完。数据中心里可以用 9000 的大箱子(约 4500 个汉字,两页多 A4),但一出公网就必须换回标准箱,因为全世界的中转站四十年来都是按标准箱的尺寸建的传送带。

链路层做的第二件事是差错检测。帧尾那 4 字节 FCS 是一个 CRC-32 校验值,接收方重算一遍,不一致就直接丢弃整帧,不通知任何人。注意这个细节:以太网只做"检错"不做"纠错",也不做"重传"。丢了就是丢了,指望上面的 TCP 去发现和补救。这是分层带来的典型分工——底层负责"不把错的数据往上递",上层负责"发现少了就要回来"。

这个分工换成大白话特别清楚:链路层是个只管验货、不管补货的收货员——箱子瘪了、封条破了,它当场扔掉,连电话都不给你打一个。"少了一箱"这件事得靠收货人自己点数发现,然后自己去催发货方补寄。这就是 TCP 存在的理由。

MAC 地址是 48 位(6 字节),写成 00:1A:2B:3C:4D:5E 这样的十六进制。前 24 位叫 OUI(Organizationally Unique Identifier),由 IEEE 分配给厂商——比如 00:50:56 属于 VMware,3C:22:FB 属于 Apple。所以拿到一个 MAC 地址,你其实能查出这块网卡是谁造的。这也是为什么手机会有"MAC 地址随机化"功能:固定的 MAC 会让商场 WiFi 探针在你没连网时也能追踪你的行踪。

交换机(Switch)是二层设备,它比 Hub 聪明的地方在于会学习:每收到一帧,就把"源 MAC ↔ 来自哪个端口"记进 MAC 地址表(也叫 CAM 表)。下次要往这个 MAC 发东西,就只从那一个端口发出去,其他端口完全安静。这一个改进带来两个巨大收益:带宽从共享变成独占(每个口都有完整速率)、碰撞域被切碎(不再需要 CSMA/CD)。如果目的 MAC 不在表里,交换机才会退化成 Hub 的行为——往所有其他口泛洪一次。

交换机比集线器聪明在哪?打个比方,集线器是那个不认人的大喇叭,交换机是一个会记事的门房:谁从哪个门进来过,他都记在小本子上;下次有人找那位,他直接指路"三号门",不再满院子喊。这一个"记本子"的改进带来两个巨大好处:每家有了独立通道、不再有人打岔。本子上没记过的人,他才会喊一嗓子问一下。

第三层 · 网络层(Network)

管"怎么从源地址找到目标地址"——跨城市、跨国家、跨大洲。

网络层就是快递的分拣中心:它不送货上门,也不管你箱子里装什么,它只干一件事——看一眼面单上写的城市,决定这箱货该扔上哪辆车。"这箱去哪座城市"是它唯一在乎的问题。

网络层是整个分层体系的"腰"——上面的传输层不管走什么线路,下面的链路层不管数据去哪个国家,只有网络层同时知道"全局目标"和"下一步该交给谁"。它的核心协议 IPv4 定义在 RFC 791(1981 年 9 月),头部 20 字节的布局四十多年没动过:

IPv4 头部(20 字节,不含选项):

 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
+-------+-------+---------------+-------------------------------+
|版本(4)|首部长 |  服务类型 TOS |        总长度(16 位)        |
+-------+-------+---------------+-----+-------------------------+
|          标识 Identification  |标志 |     片偏移 Offset       |
+---------------+---------------+-----+-------------------------+
|  生存时间 TTL |   协议号      |       首部校验和              |
+---------------+---------------+-------------------------------+
|                     源 IP 地址(32 位)                       |
+---------------------------------------------------------------+
|                   目的 IP 地址(32 位)                       |
+---------------------------------------------------------------+

协议号(Protocol)的常见取值:1=ICMP  6=TCP  17=UDP  41=IPv6  89=OSPF
TTL 每过一台路由器减 1,减到 0 就丢弃并回一个 ICMP 超时 —— traceroute 就靠这个原理

网络层最本质的特征是"尽力而为"(Best-Effort):它不承诺送到、不承诺顺序、不承诺不重复。路由器缓冲区满了就丢包,丢了也不告诉你。这个看似"不负责"的设计恰恰是互联网能长到今天这个规模的原因——因为路由器不需要为每一条连接保存状态,它只需要"看一眼目的 IP,查表,转发出去,忘掉"。这叫无连接的分组交换,与传统电话网的"电路交换"(每通电话都要在交换机里占用一条固定通路)形成鲜明对比。

"尽力而为"翻译成人话就是一家不保价、不承诺时效、丢了不赔的搬运队。听着不靠谱,可这恰恰是它能长这么大的原因:分拣中心不需要为每一票货建档案,它只需要"看一眼地址、扔上车、忘掉"——正因为记性差,它才能一天处理几亿件。要是每件货都得建档跟踪到底,这套系统早就撑不住了。

路由器(Router)是三层设备。它和交换机的根本区别是:交换机查 MAC 表,路由器查路由表;交换机不改包,路由器每一跳都要重写链路层头部。一个包从你家路由器走到百度机房,IP 头里的源 IP 和目的 IP 全程不变(除了 NAT 场景),但链路层的 MAC 头部被重写了十几次——每一跳都是"新的一段本地投递"。用邮政类比:信封上的最终地址不变,但每个中转站都会贴一张新的"下一站"标签。

再把这条钉一遍,因为它是全篇最重要的一条:面单上的收件地址从头到尾一个字没改,但"下一站送哪"的标签被重贴了十几次。IP 定终点,MAC 定下一站——搞混这两件事,是初学网络最常见的一个坎。

交换机(二层)路由器(三层)
看哪个头部以太网头(MAC)IP 头(IP 地址)
查什么表MAC 地址表 / CAM路由表 / FIB
表怎么来的自动学习源 MAC静态配置 + OSPF/BGP 动态学习
会修改包吗不改(VLAN 场景会加标签)改:TTL 减 1、重算校验和、换 MAC 头
广播怎么处理转发(同一广播域)拦截(隔离广播域)
典型转发延迟微秒级数十微秒到毫秒级

第四层 · 传输层(Transport)

管"端到端的可靠传输"——你的电脑到百度的服务器,中间可能经过几十个路由器,传输层确保数据完整到达。

传输层的关键词是"端到端"。请仔细体会这三个字和网络层"点到点"的区别:网络层关心的是"这个包怎么从路由器 A 挪到路由器 B",传输层关心的是"你手机上的微信进程和腾讯服务器上的那个进程之间,这次对话有没有说清楚"。中间的几十台路由器完全看不到也不关心传输层在干什么——它们只拆到 IP 头就停手了。

"端到端"和"点到点"的区别,打个比方就是"你和收信人的对话"和"两个中转站之间的交接":你在信里写"记得带伞",这句话是你和收信人之间的事;而"这袋邮件从北京站交给了郑州站"是中转站之间的事。中转站从头到尾不知道也不关心你在信里聊什么天气——它们只拆到信封那一层就停手了。

传输层还引入了一个新概念:端口号。IP 地址只能定位到"哪台机器",但一台机器上同时跑着浏览器、微信、网易云、后台更新程序,来的数据该交给谁?答案就是那个 16 位的端口号。这个"IP + 端口"的组合叫套接字(Socket),而"源 IP + 源端口 + 目的 IP + 目的端口 + 协议"这五个值叫五元组——操作系统就是靠五元组唯一识别每一条连接的。

端口范围名称谁在用例子
0 ~ 1023知名端口 Well-Known由 IANA 统一分配,Linux 下需 root 才能监听80 HTTP、443 HTTPS、22 SSH、53 DNS、25 SMTP
1024 ~ 49151注册端口 Registered厂商向 IANA 登记3306 MySQL、6379 Redis、8080 备用 HTTP、27017 MongoDB
49152 ~ 65535动态/私有端口 Ephemeral系统随机分配给客户端你浏览器每开一个连接就随机占一个

这里有个能算出来的现实限制:一台客户端机器对同一个目标 IP + 端口,最多只能建约 28000 条并发连接(Linux 默认 ephemeral 范围 32768~60999)。这就是高并发压测机器为什么要调 net.ipv4.ip_local_port_range 内核参数的原因。端口号只有 16 位这个 1981 年的决定,至今还在约束着 2026 年的服务器架构。

那个"约 28000 条并发连接"的上限说白了就是:这栋楼虽然有六万五千个房间,但你一个人手上能同时租的只有中间那两万八千间——不是楼不够大,是系统给客户端划的那一段号码就那么宽。压测机器要改内核参数,就是去把这个可租区间拓宽一点。

第五层 · 会话层(Session)

管"怎么建立、维持、断开一次对话"——比如视频会议开始时握手,结束时说拜拜。

会话层是七层里最"名存实亡"的一层,也是学习者最容易困惑的一层。因为在今天的 TCP/IP 世界里,你几乎找不到一个"纯粹的会话层协议"——它的职责被分散到了别处:连接的建立与拆除被 TCP 拿走了,会话的身份识别被应用层的 Cookie/Token 拿走了,加密会话的恢复被 TLS 的 Session Resumption 拿走了。

会话层说白了就是过去电话局里那个接线员:帮你拨通、中间保持着别断、聊完帮你挂上。今天这个岗位被裁掉了——拨通和挂断的活儿 TCP 接了,"记得你是谁"的活儿 Cookie 接了,"上次聊到哪"的活儿 TLS 接了。岗位没了,但活儿一件没少。

但 OSI 当年把它单独立为一层是有理由的。会话层原本要解决三个真实问题:①会话恢复——大文件传了 80% 断了,重连后能从断点继续,而不是重头再来;②对话控制——规定这次通信是全双工(双方随时说)、半双工(轮流说,要抢"令牌")还是单工;③同步点(Synchronization Point)——在数据流里插标记,出错时回滚到最近的标记而不是最开头。这三件事在今天分别对应 HTTP Range 断点续传、WebSocket 的双向通信、以及数据库事务的检查点。

它当年要解决的那三件事,用生活话讲就是: 一本书抄到第 80 页被打断了,回来接着抄第 81 页,而不是从头再抄(断点续传); 说清楚这次是"两人都能随时插话"还是"轮流说、说完把话筒递过去"(对话控制); 每抄十页就折个角,抄错了退回最近那个折角,不用整本重来(同步点)。这三件事今天全都还在,只是换了别人干。

你能在现实中找到的最接近"会话层"的东西,大概是这几个:TLS 的 session ticket(让你重连时跳过完整握手)、SSH 的连接复用(一个 TCP 连接上跑多个逻辑通道)、SOCKS5 代理、以及 RPC 框架里的"会话上下文"。所以准确的说法是:会话层的功能真实存在,只是它没有一个独立的协议层去承载。

第六层 · 表示层(Presentation)

管"数据格式怎么统一"——你的电脑用 UTF-8,对方的电脑用 GBK,表示层负责翻译。

表示层解决的核心矛盾是:两台机器内部表示数据的方式可能完全不同。这不是杞人忧天,而是 1980 年代的真实痛点。当时的机器里,IBM 大型机用 EBCDIC 编码字符,小型机用 ASCII;摩托罗拉 68000 处理器是大端字节序(Big-Endian),Intel x86 是小端(Little-Endian)。同一个整数 0x12345678 在两种机器的内存里字节顺序正好相反。如果不做转换,把数字 305419896 发过去,对方读出来会是 2018915346。

表示层干的活儿说白了就是翻译。而"字节序不同"这件事听着玄,换个说法就明白了:同一串数字,一边习惯从左往右念,另一边习惯从右往左念——就像有人写日期是"2026-08-02",有人写成"02/08/2026",数字一个没差,读出来完全是两个日子。不约好读法,两边都觉得自己没错,可结果差了十万八千里。

网络世界最终的解法是规定一个"网络字节序"(Network Byte Order,统一用大端),所有协议头部里的多字节字段都必须按这个顺序写。这就是 C 语言里那几个函数存在的原因:

// 主机字节序 <-> 网络字节序 转换(socket 编程必用)
htons(port);    // host to network short   —— 16 位,端口号用
htonl(addr);    // host to network long    —— 32 位,IP 地址用
ntohs(port);    // network to host short   —— 收到后转回来
ntohl(addr);    // network to host long

// 在 x86(小端)上,htons(80) 会把 0x0050 变成 0x5000
// 在大端机器上,htons 是空操作(什么都不做)
// 这就是"表示层"思想在代码里的直接体现

"网络字节序"这个解法特别朴素:既然两边习惯不一样,那就规定"上路的时候一律按这一种写法来"——好比国际快递面单强制要求用英文填写,不管寄件人母语是什么。到了自己家里你爱怎么念怎么念,但出门必须按公版格式。那几个 htons 函数干的就是"出门前换成公版、进门后换回自家习惯"这件事。

TLS 被归到表示层是个经典的争议话题。严格按 OSI 的定义,加密确实是表示层的活;但按 TCP/IP 的实现,TLS 明明是跑在 TCP 之上、HTTP 之下的一个"夹层"。所以你会看到两种说法都有人用。业内比较通行的折中叫法是把它称为"4.5 层"或"会话层/表示层之间"——这个别扭的编号本身就说明了 OSI 的层划分和真实实现之间的错位。

今天你能明确指认为"表示层工作"的事情包括:字符编码转换(UTF-8 / GBK / ASCII)、序列化格式(JSON / Protocol Buffers / ASN.1 / XML)、媒体编解码(JPEG / PNG / H.264 / AAC)、压缩(gzip / brotli / zstd)、以及加密。这些活儿在今天全都由应用程序自己的库来做,操作系统的网络栈完全不插手——这正是 TCP/IP 把表示层合并进应用层的现实依据。

为什么这一层今天"名存实亡"?说白了就是这些活儿全被搬进了每个应用自己的厨房:编码转换、压缩、加密、编解码,现在都是应用自己带的库在干,操作系统的网络栈一根手指都不碰。岗位还在,只是不再由公共部门统一负责,改成家家自己动手了。

第七层 · 应用层(Application)

最高层——用户直接感知的服务

应用层有个需要澄清的常见误解:应用层 ≠ 你的应用程序。Chrome 浏览器本身不是"应用层",它使用应用层协议(HTTP)。应用层指的是那些"规定了应用之间怎么对话"的协议规范。分界线在于:协议是双方共同遵守的公共约定,程序是单方的实现。Chrome 和 Firefox 是两个完全不同的程序,但它们说的是同一种 HTTP。

这个区别打个比方就一秒懂:"应用层协议"好比餐厅通用的那套点菜规矩(先看菜单、再报菜名、然后等上菜),"应用程序"是具体某一家餐厅。规矩是大家共用的公共约定,餐厅是各家自己的实现。Chrome 和 Firefox 是两家不同的餐厅,但用的是同一套点菜规矩——所以你在哪家都会点菜。

应用层协议数量最多、变化最快,因为它离业务最近。粗略分类的话有这么几类:①资源获取类——HTTP、FTP、Gopher;②消息投递类——SMTP、IMAP、POP3、XMPP;③名字解析类——DNS、LDAP、WHOIS;④远程控制类——SSH、Telnet、RDP、VNC;⑤基础设施类——DHCP、NTP、SNMP、Syslog;⑥实时媒体类——RTP、RTSP、SIP、WebRTC。

OSI 原本还给应用层设计了一套自己的协议家族,名字你可能听过但从没用过:FTAM(文件传输,对标 FTP)、X.400(电子邮件,对标 SMTP)、X.500(目录服务,对标 DNS)、VT(虚拟终端,对标 Telnet)。这些协议里唯一活到今天的是 X.500 的简化版——LDAP,以及 X.509 证书格式(你每次访问 HTTPS 网站验证的那张证书,格式就是 OSI 留下的遗产)。所以说 OSI"完全失败"并不公平,它的部分设计以一种"打散混入"的方式留在了今天的互联网里。

这一段的结论挺有意思:OSI 那套自己设计的协议家族基本全军覆没,但它留下了几件"遗物"还在天天被用——你每次访问 HTTPS 网站时浏览器验的那张证书,格式就是 OSI 留下的 X.509。好比一家倒闭的老店,招牌没了,但它当年定的那套单据格式,整个行业至今还在用。

层与层之间怎么"交接":服务与原语

前面讲了每层做什么,但还有一个更精细的问题没答:层与层之间到底是怎么把数据递过去的?OSI 为此定义了一套相当学术的术语体系。虽然听起来枯燥,但理解它能让你彻底搞懂"封装"到底封的是什么。

这几个缩写听着吓人,换成套箱子的说法一秒就懂:SDU=上层递给你的那个盒子(你不许打开);PCI=你自己要贴的那张面单;PDU=贴好面单的整个箱子(也就是你递给下一层的东西);SAP=面单上写着"里面装的是生鲜/图书/数码"那一栏,收货那头靠它决定交给哪个部门。四个词,说的全是"套箱子"这一件事。

术语全称什么意思举例
PDUProtocol Data Unit本层要发出去的完整数据块 = 本层头部 + 上层交下来的东西TCP 段、IP 包、以太网帧
SDUService Data Unit上层交下来、本层原封不动搬运的那部分数据对 IP 来说,整个 TCP 段就是它的 SDU
PCIProtocol Control Information本层自己加的控制信息,也就是"头部"IP 头的 20 字节
SAPService Access Point上下层之间的"接口地址",指明数据交给上层的谁IP 头里的协议号、以太网头里的 EtherType

用一句话串起来:第 N 层的 PDU = 第 N 层的 PCI(头部) + 第 N 层的 SDU(也就是第 N+1 层的 PDU)。这个递归定义就是"封装"的严格数学表述。第 N 层永远不去看自己 SDU 的内容——那是上层的私事,看了就叫"违反分层"。

那句递归定义翻译成人话就一句:我的箱子 = 我贴的面单 + 上一层递给我的整个箱子。就这么套下去,套七层。而"不许看 SDU 的内容"这条纪律,说白了就是"不许拆别人的箱子"——你只管在外面再套一层、贴上自己的单子,里头装什么不是你该管的。

OSI 还定义了四种服务原语(Service Primitive),描述层间交互的四种动作:Request(上层向下层请求做某事)、Indication(下层向上层通知有事发生)、Response(上层对通知作出回应)、Confirm(下层告知上层"你的请求办完了")。在 socket 编程里你能直接对应上:connect() 是 Request,服务器端 accept() 返回是 Indication,listen() 队列里的握手完成是 Confirm。

SAP 这个概念特别值得多说一句,因为它是"解封装时怎么知道该交给谁"的答案。接收方拆掉以太网头后,怎么知道里面是 IP 包还是 ARP 包?看 EtherType 字段(0x0800 = IPv4)。拆掉 IP 头后怎么知道里面是 TCP 还是 UDP?看协议号字段(6 = TCP)。拆掉 TCP 头后怎么知道该交给哪个程序?看目的端口(443 = 交给 HTTPS 服务)。这三个字段就是三层 SAP,它们构成了一条完整的"向上分发链"。

这三个字段说白了就是仓库里的三道分拣:拆掉最外层大箱,看标签知道该送去"生鲜区"还是"图书区"(EtherType);进了区,再看标签知道是"冷藏"还是"冷冻"(协议号);最后看货架号,知道该上哪一格(端口)。每一层的标签只回答"下一步交给谁"这一个问题,问完就算完成任务。

数据怎么"穿层"

你发一封邮件,数据是这样"穿"过七层的:

下面这七步,说白了就是把一句"Hello"层层套箱、扔上货车的全过程。你在邮件框里敲的那五个字母,出门时已经被裹了六层包装——而收件那头会把这六层原封不动地一层层拆开,最后拿到的还是那五个字母,一个都不多不少。

7. 应用层

你写"Hello" → 邮件客户端把它包装成 SMTP 协议格式。

6. 表示层

SMTP 数据被加密(TLS)、编码(Base64)。

5. 会话层

建立到邮件服务器的会话连接。

4. 传输层

数据切成 TCP 段,加序号,准备可靠传输。

3. 网络层

加上 IP 头(源 IP + 目标 IP),路由器开始选路。

2. 数据链路层

加上 MAC 头(源 MAC + 下一跳 MAC),交换机转发。

1. 物理层

变成电信号/光信号,通过网线/光纤发出去。

到了对方机器,再反过来一层层"剥皮"——从 1 到 7,最终看到"Hello"。

Analogy · 洋葱

数据包像一颗洋葱——应用层数据在最里面,每往下一层就包一层"皮"(头部信息)
到了对方机器,再从外到内一层层剥皮,最后看到最里面的数据。
这就是"封装"和"解封装"。

封装的字节账:一句话变成一个帧

"洋葱"的比喻很好懂,但工程师需要看到数字。我们拿一个最小的 HTTP 请求算一遍,看看它从应用层走到物理层时到底胖了多少:

下面这笔账值得慢慢看,因为它把"分层的代价"第一次变成了具体数字。打个比方,就是称一下"一件礼物"和"最终那个包裹"分别多重——礼物 87 克,包好以后 165 克,泡沫和纸箱占了将近一半。

【应用层】HTTP 请求体(假设 87 字节)
  GET /index.html HTTP/1.1\r\nHost: example.com\r\n...\r\n\r\n
  = 87 字节

【传输层】+ TCP 头部 20 字节(无选项时)
  [TCP头 20B][HTTP 87B]                 = 107 字节  → 叫"TCP 段"

【网络层】+ IPv4 头部 20 字节
  [IP头 20B][TCP头 20B][HTTP 87B]        = 127 字节  → 叫"IP 包"

【链路层】+ 以太网头 14 字节 + 尾部 CRC 4 字节
  [以太头 14B][IP 127B][FCS 4B]          = 145 字节  → 叫"以太网帧"
  注意:不足 60 字节还要填充到 60,这里够长不用填

【物理层】+ 前导码 7B + 帧起始定界符 1B + 帧间隙 12B
  线上实际占用 = 145 + 8 + 12          = 165 字节的"线时"

结论:87 字节的有效内容,占用了 165 字节的线路资源
      协议开销 = (165 - 87) / 165 ≈ 47%

47% 的开销听起来很惊人,但这是因为我们选了一个很小的报文。如果传的是 1460 字节的满载数据段(这是以太网上 TCP 的标准 MSS:1500 − 20 IP − 20 TCP = 1460),账就完全不同了:1460 + 54 = 1514 字节帧,开销降到约 3.6%。这解释了一条重要的性能规律:包越小,协议开销占比越高。

反过来说,这也解释了为什么小包场景对网络设备是噩梦。一台千兆网卡跑满 1518 字节的大包,每秒约 8.1 万个包;换成 64 字节小包,每秒要处理 148.8 万个包——包处理次数暴涨 18 倍,而有效吞吐反而只有原来的几分之一。这就是网络测试报告里总要标明"64 字节小包线速转发能力"的原因,它才是设备真正的极限指标。

这段数字换算成生活话就特别有画面:同一辆货车,运大件时一天能跑 8 万趟;改运小件,一天要跑 149 万趟,可实际运走的东西反而少了。累的不是"运了多少东西",而是"处理了多少票单子"。这就是为什么设备参数表上非要标"小包线速转发能力"——那才是它真正的极限。

解封装的顺序则是严格反向的,而且每一步都要做一次"该交给谁"的判断:

网卡收到电信号
  → 恢复成比特流,校验 CRC,不对就静默丢弃         【物理层/链路层】
  → 检查目的 MAC 是不是我的(或广播/多播)
     不是我的 → 丢弃(网卡混杂模式除外)           【链路层】
  → 看 EtherType = 0x0800 → 交给 IP 模块           【SAP 分发】
  → 检查 IP 头校验和;检查目的 IP 是不是我          【网络层】
  → 若有分片则重组;看协议号 = 6 → 交给 TCP 模块    【SAP 分发】
  → 按五元组找到对应的连接(socket)                【传输层】
  → 校验和、按序号排入接收缓冲区、发 ACK
  → 看目的端口 = 443 → 唤醒监听该端口的进程         【SAP 分发】
  → 应用程序 read() 拿到字节流                      【应用层】

七层怎么记:几种靠得住的助记法

七层的顺序是面试和考试的必答项,硬背容易串。下面几种方法挑一个用就行:

方向英文首字母句中文口诀
自下而上(1→7)Please Do Not Throw Sausage Pizza Away物、链、网、传、会、表、应
自上而下(7→1)All People Seem To Need Data Processing应、表、会、传、网、链、物
中文谐音(1→7)"输,示给用"

比死记硬背更有效的是理解为什么是这个顺序。从下往上看,每一层解决的问题范围在逐步扩大:物理层管"一根线上的信号",链路层管"一个局域网内的相邻两台机器",网络层管"全球任意两台机器",传输层管"两个进程之间",再往上就不是"送到"的问题而是"怎么理解"的问题了。顺序的逻辑是:先解决"能不能到",再解决"能不能懂"。

为什么是这个顺序?换成大白话就是:下面四层在解决"东西怎么送到你手上",上面三层在解决"送到了你能不能看懂"。好比先得把一封外文信送到你家(那是运输的事),然后才轮到找人翻译、拆开阅读(那是理解的事)。顺序颠倒不了——信还没到,谈翻译毫无意义。

还有一个实用的记忆锚点:1、2、3、4 层是"网络工程师的世界",5、6、7 层是"程序员的世界"。前四层的功能几乎全部在操作系统内核和网络硬件里实现,你写业务代码时碰不到;后三层的功能在你的应用代码和第三方库里实现,你天天在写。这条线也正好是 TCP/IP 把 5、6、7 合并成一个"应用层"的分界处。

那条"1-4 层是网络工程师的世界、5-7 层是程序员的世界"的分界特别实用。打个比方,前四层是小区的水电管网(物业在管,你家里看不见),后三层是你家厨房里的锅碗瓢盆(全靠你自己张罗)。水管什么材质你从不操心,但今晚炒什么菜只能你自己定。

为什么要七层?三层行不行?

理论上可以——但分七层的好处是"每层可以独立升级"

不过要老实说:七层这个数字本身并没有什么神圣性。OSI 委员会最初讨论过五层、六层、八层的方案,七层是一个折中投票的结果。判断"该分几层"的原则在 ISO 7498 的附录里写得很清楚,大致是:①功能明显不同的应该分开;②功能相似的应该合并以免层数过多;③每层的边界应选在跨层交互最少的地方;④边界的位置要方便未来在这里插入新技术

那四条原则说白了就是装修时怎么划分包工队:①活儿性质不一样的分开找人(水电和木工不能一个人干);②太琐碎的合并了算(别为了贴一块砖单独请个队);③交界处要选在"两边扯皮最少"的地方;④接口留好,以后想换个新工艺不用把墙砸了。分几个队不是拍脑袋定的,是按这四条算出来的。

按这几条原则回头审视,OSI 自己也有不达标的地方:会话层和表示层的功能太少、独立性太弱,实践中根本撑不起一个层的分量;而数据链路层又太重,IEEE 后来不得不把它拆成 LLC(逻辑链路控制)和 MAC(介质访问控制)两个子层。所以"七层"更应该被理解成一份分层思路的示范作业,而不是一个必须严格遵守的数量规定。

那么"三层行不行"?实践中真有三层的模型:ATM 网络就是三层(物理、ATM、ATM 适配层),蓝牙、Zigbee 这类短距无线协议栈也常常只有三到四层。层数取决于场景复杂度——一个只需要在同一间屋子里传几十字节的传感器网络,确实不需要"全球路由"和"跨平台编码转换"这两层。分层的层数应该由问题的复杂度决定,而不是由标准文件规定。

再补一句大白话:七层这个数字压根没什么神圣的,它是投票投出来的。OSI 自己就有两层(会话、表示)虚得撑不起一层的分量,还有一层(链路层)重得后来被迫拆成了两半。好比一家小饭馆压根不需要"采购部、切配部、炒锅部、摆盘部、传菜部"五个建制——两个人就能把这五件事全办了。层数该由事情的复杂度定,不由文件定。

OSI 为什么输了:一场教科书级的失败复盘

1990 年前后,几乎所有人都认为 OSI 会赢。它有 ISO 和 ITU 两大国际组织背书、有欧洲各国政府支持、有美国 GOSIP 的采购强制令、有 IBM、DEC、西门子等巨头参与制定。而 TCP/IP 只是"美国国防部资助的一个研究项目"。结果十年后 OSI 协议栈彻底消失,TCP/IP 统治全球。这个反转的原因,是网络史上被反复分析的经典案例:

这个反转说白了就是:一个开了七年会才拿出完美方案的委员会,输给了一群早就把东西做出来、还免费送给全世界抄的工程师。下面六条原因,条条都是这句话的展开。

历史学家 Andrew Russell 在《Open Standards and the Digital Age》里给出的判词很精准:"OSI 的失败不是技术的失败,是一种组织哲学的失败。"OSI 相信标准应该由权威机构自上而下设计,TCP/IP 相信标准应该由实践自下而上涌现。四十年后回看,后者赢了——而且不只在网络领域赢了,开源软件运动、Web 标准、区块链协议,走的都是同一条路。

把这六条压缩成一句生活话:OSI 像一份写得极其漂亮、但要花钱买、而且做起来要一整年的装修图纸;TCP/IP 像邻居已经装好的那套房子,钥匙还免费给你配一把、图纸随便抄。你会选哪个?全世界都选了后者。这不是技术之争,是"能不能现在就用上"之争。

Insight · 一个时间线对照

1969 ARPANET 上线,第一份 RFC 发布
1974 Cerf 与 Kahn 发表 TCP 论文;IBM 发布 SNA
1977 ISO 成立 SC16,OSI 项目启动
1981 RFC 791(IP)、RFC 793(TCP)定稿
1983 ARPANET 全网切到 TCP/IP;4.2BSD 附带免费实现
1984 OSI 成为 ISO 7498 国际标准 —— 但已经晚了一年
1990 美国 GOSIP 强制采购 OSI;万维网诞生
1995 美国政府放弃 GOSIP 强制要求,实质承认 TCP/IP 胜出
可以看到,OSI 拿到"官方标准"身份的那一年,TCP/IP 已经完成了全网部署。这就是"事实标准"的力量。

那 OSI 今天还有什么用

既然协议栈死了,为什么每本教材、每场面试都还在讲 OSI?因为它活成了另一种东西:OSI 不是实现标准,而是全行业的"共同语言"和"思维脚手架"。

换成大白话:OSI 的协议死了,但它的"话术"活了下来,成了整个行业的普通话。就像一家倒闭的老字号,菜没人做了,可它当年给菜品编的那套号(一号菜、七号菜)全行业还在用——你说"七层问题",所有人立刻知道你在说什么。

你几乎每天都会在工作中听到这套术语,而且说的人心里想的都是 OSI 的编号:

行业说法实际含义对应 OSI 层
"这是个二层问题"MAC 地址、VLAN、交换机、ARP 相关第 2 层
"三层交换机"能按 IP 路由的交换机第 3 层
"四层负载均衡"只看 IP + 端口来分流,不解析内容(LVS、F5 的 L4 模式)第 4 层
"七层负载均衡"解析 HTTP 内容,按 URL / Header / Cookie 分流(Nginx、ALB)第 7 层
"L2 打通"让两个机房像在同一个局域网里(VXLAN 等)第 2 层
"七层 DDoS"伪造大量正常 HTTP 请求打垮应用,而非用流量灌满带宽第 7 层
"第八层问题"行业黑话——问题出在"用户"身上,不是机器不存在的第 8 层

它的第二个价值是故障定位的思维框架。一个有经验的工程师面对"网站打不开"时不会乱猜,而是自下而上一层层排除:线插了吗(1 层)→ 网卡拿到 IP 了吗、ARP 通吗(2 层)→ ping 网关和外网 IP 通吗(3 层)→ 目标端口能连上吗(4 层)→ TLS 证书有没有过期(表示层)→ HTTP 返回什么状态码(7 层)。这个流程之所以高效,正是因为下层不通时上层必然不通,所以从下往上排能最快缩小范围

这套排查顺序说白了就是医院分诊的固定问诊单:先量体温、再测血压、再问哪儿疼,一步步把范围缩到某个科室。之所以必须从下往上,是因为"下层不通时上层必然不通"——水管没水,你研究水龙头的样式毫无意义。先看线插了没,再看有没有 IP,再看 ping 得通不通,最后才轮到看网页返回什么码。

第三个价值是教学。TCP/IP 四层把会话、表示、应用挤在一起,虽然贴近实现,但会让初学者以为"加密"和"HTTP"是一回事、"断点续传"和"网页渲染"是一个层次的问题。OSI 的七层虽然过于工整,却清楚地告诉你这些是性质完全不同的关注点。先学 OSI 再学 TCP/IP,几乎是所有教材的选择,原因就在这里。

第三个价值用大白话讲就是:TCP/IP 那四层像一份"实际怎么干"的施工笔记,OSI 七层像一份"概念上该分几件事"的课堂板书。施工笔记贴近现实,但会让新手把好几件不同性质的事看成一件——以为"加密"和"打开网页"是一个层次的问题。所以教材总是先讲板书,再讲笔记。

面试常考点与常见坑

OSI 是网络面试的高频开场题。下面这些问题几乎每轮都会碰到,而且不少有"看起来对但其实错"的标准坑:

这一节的用法很实在:下面每一条都不只是"标准答案",而是一个"往深答一层"的抓手。面试考的从来不是你背没背下七层顺序,而是你知不知道哪儿有争议、争议在哪儿——主动把坑说出来,比选一个答案更能显出你真的懂。

Recap · 收束

OSI 七层 = "网络世界的分工表"。每层只管一件事,互不干扰,坏了单独修。
虽然互联网实际用的是 TCP/IP 四层(下一篇讲),但 OSI 七层是理解网络分层的最佳教材——面试必考,排查问题必用。

☰ 主页
Xue Hai Wu Ya · Network · § 2.1 · OSI Model