一、应用层:网络服务如何真正面向用户?
在计算机网络中,我们已经有了传输层、网络层和数据链路层,为什么还需要应用层?
因为前面这些层主要解决的是如何在网络中传输数据,而用户真正需要的是某种具体服务,例如浏览网页、发送邮件、下载文件。
应用层正是为这些具体需求而存在的。
1.1 User Agent:用户代理
在应用层中,有一种直接代表用户与网络服务交互的程序,叫作 User Agent(用户代理)。
例如浏览器、邮件客户端等。
它可以从两个方向理解:
对上:提供用户交互界面和应用功能。
例如我们在浏览器中输入网址、点击链接、提交表单。
对下:将用户行为转换成应用层协议消息。
例如浏览器把访问网页的操作转换为 HTTP 请求,交给下层网络进行传输。
text
用户
│
输入网址、点击链接
│
▼
User Agent
(浏览器)
│
生成 HTTP 请求
│
▼
应用层协议
│
▼
下层网络协议
│
▼
网络
因此,User Agent 可以看作连接用户和网络通信机制的桥梁。
需要注意,并不是所有应用层程序都叫 User Agent,服务器程序同样属于应用层程序。
1.2 应用层协议究竟规定什么?
由于应用层直接服务于具体需求,因此不同应用所使用的协议也各有特点。
例如:
- HTTP:规定网页请求、响应、状态码等。
- DNS:规定域名查询、应答及资源记录的格式。
- SMTP:规定电子邮件如何发送、转发。
- FTP:规定文件如何上传、下载以及管理。
这些协议有一个共同点:
应用层协议不仅定义数据怎么表示,还定义通信双方应该怎样理解和处理这些数据。
概括起来就是:
应用层协议 = 通信语义 + 数据格式 + 交互规则
也可以理解为:
传什么、什么时候传、传完之后怎么解释。
例如,HTTP 请求中的:
http
GET /index.html HTTP/1.1
Host: example.com
服务器通过 GET 知道客户端希望获取资源,通过 /index.html 知道具体请求什么。
而 TCP 并不理解 GET 的语义,它主要负责提供可靠、有序的字节流传输。
这正是分层设计的意义。
- 应用层:处理具体应用的通信规则。
- 传输层:提供端到端的数据传输服务。
- 网络层:解决跨网络寻址与转发问题。
- 数据链路层:处理特定链路上的帧传输。
当然,应用层不是什么底层问题都不用考虑。例如 HTTP 可以规定缓存、超时后的处理策略,应用程序也可能自行重试失败的请求。
但应用层不需要亲自实现路由选择、TCP 重传等机制。
二、应用层的两种典型架构:C/S 和 P2P
应用层程序需要互相通信,而它们之间的组织方式主要有两种典型架构。
2.1 C/S(Client/Server):客户端与服务器
C/S 架构中,服务器提供服务,客户端向服务器发起请求。
例如:
text
客户端 A ────┐
│
客户端 B ────┼──── 服务器
│
客户端 C ────┘
在聊天系统中,可能存在:
text
用户 A → 服务器 → 用户 B
但需要注意,服务器并不只是负责转发消息。
服务器还可能负责:
- 存储:例如邮箱、云盘、数据库。
- 权限控制:验证用户是否有权访问资源。
- 状态管理:记录用户登录状态、业务数据。
- 数据处理:执行查询、计算或业务逻辑。
例如,用户访问一个购物网站,并不是简单地让服务器将请求转发给其他用户,而是由服务器处理商品查询、订单等业务。
C/S 的优点是管理集中,服务相对容易维护;缺点是服务器可能成为性能瓶颈或单点故障来源,需要通过冗余部署、负载均衡等方式改善。
2.2 P2P(Peer-to-Peer):对等网络
P2P 架构中,参与通信的节点可以直接向其他节点提供服务。
例如:
text
节点 A ───── 节点 B
│ │
│ │
节点 C ───── 节点 D
每个节点既可以请求数据,也可以向其他节点提供数据。
典型应用有部分分布式文件共享系统。
不过,P2P 并不意味着完全没有服务器。
例如,两台处于 NAT 后面的计算机,可能不知道对方的可连接地址。
它们可以借助信令服务器、STUN 等机制发现连接信息,尝试建立直连;无法直连时,也可能借助中继服务器传输数据。
因此:
C/S 和 P2P 的主要区别是应用中各节点的角色与组织方式,而不是简单地看有没有服务器。
三、DNS:从域名到 IP 地址
3.1 DNS 为什么存在?
计算机网络使用 IP 地址进行网络层寻址。
但是用户通常不愿意记忆一串数字,因此我们使用域名。
例如:
text
www.example.com
DNS(Domain Name System,域名系统)的重要功能之一,就是帮助我们查询域名对应的 IP 地址。
text
www.example.com
│
▼
DNS
│
▼
IP 地址
但 DNS 不只是简单的域名与 IP 对照表。
一个域名可以对应多个 IP 地址,多个域名也可以对应同一个 IP 地址。
此外,DNS 还保存邮件服务器、服务发现、别名等多种信息。
3.2 DNS 为什么采用层次化结构?
假设整个互联网只有一台 DNS 服务器,它保存全球所有域名的信息。
随着域名数量增加,这台服务器不仅存储压力巨大,还会形成严重的性能瓶颈和单点故障。
所以,DNS 采用了分布式、层次化的管理结构。
理论上,DNS 域名空间可以包含很多层级。
以:
text
www.example.com.
为例:
text
.(Root)
│
com
│
example
│
www
其中末尾的 . 表示 DNS 根域,通常在日常输入时省略。
实际 DNS 查询中,经常可以看到三个重要角色:
1. Root DNS:根 DNS
根服务器主要提供顶级域的委托信息,例如:
text
.com 应该去询问哪些 DNS 服务器?
.top 应该去询问哪些 DNS 服务器?
2. TLD DNS:顶级域 DNS
例如负责 .com 的 DNS 服务器,可以告诉解析器:
text
example.com 由哪些权威 DNS 服务器负责?
3. Authoritative DNS:权威 DNS
权威服务器保存它所负责区域的权威记录,例如:
text
www.example.com → 192.0.2.80
api.example.com → 192.0.2.81
这里的 IP 是文档示例地址。
需要特别注意:
域名有多少级,并不意味着就一定要访问多少级 DNS 服务器。
虽然常见解析路径可以简化为:
text
Root → TLD → Authoritative DNS
但 DNS 实际上依据的是区域委托关系。
例如 a.b.example.com 可能直接由 example.com 的权威服务器管理,也可能将某个子域单独委托给其他 DNS 服务器。
3.3 DNS 查询的完整过程
假设用户访问:
text
www.example.com
首先,系统可能会检查本机已有的信息,例如浏览器缓存、系统 DNS 缓存、hosts 文件等。
如果已经找到可用结果,就可能直接使用。
否则,通常需要向配置的递归 DNS 服务器查询。
递归 DNS 可能是:
- 运营商提供的 DNS。
- 企业网络中的 DNS。
- 公共 DNS,如
8.8.8.8、1.1.1.1。 - 自己部署的递归解析器。
如果递归 DNS 已经缓存了结果,就可以直接回答。
如果没有,它通常需要继续查询。
text
用户主机
│
│ 递归查询:www.example.com?
▼
递归 DNS
│
│ ① 查询
▼
Root DNS
│
│ 返回 .com 的委托信息
▼
递归 DNS
│
│ ② 查询
▼
.com DNS
│
│ 返回 example.com 的委托信息
▼
递归 DNS
│
│ ③ 查询
▼
权威 DNS
│
│ 返回 www.example.com 的 A 记录
▼
递归 DNS
│
│ 返回结果
▼
用户主机
这里需要区分两个概念。
递归查询:
客户端要求 DNS 解析器完成查询,返回最终结果或相应错误。
可以理解为:
我把问题交给你,你负责帮我查到底。
迭代查询:
某台 DNS 服务器不一定提供最终答案,而是告诉查询者下一步应该询问谁。
可以理解为:
我不知道最终答案,但我知道你应该去问谁。
因此,典型情况下:
- 用户主机向递归 DNS 发起递归查询。
- 递归 DNS 再逐步向 DNS 层级中的服务器发起迭代查询。
不过,递归 DNS 不一定每次都走完整过程,因为缓存可能保存了最终结果或中间的委托信息。
3.4 DNS 资源记录(RR)
DNS 中存储的信息称为 Resource Record(资源记录),简称 RR。
教学时可以将其简化为四元组:
text
(name, value, type, ttl)
其中:
name:记录所属的域名。value:记录内容。type:记录类型。ttl:允许缓存的时间。
例如:
dns
www.example.com. 300 IN A 192.0.2.80
表示:
text
域名:www.example.com
类型:A
IPv4:192.0.2.80
TTL:300 秒
TTL(Time To Live)非常重要。
假设一条记录初始 TTL 为 300 秒,缓存中经过了 15 秒,那么剩余 TTL 可能是:
text
285 秒
可以将 TTL 理解为 DNS 缓存的倒计时沙漏。
倒计时结束后,普通缓存结果便不再有效,解析器通常需要重新获取记录。
这也是为什么刚刚修改域名解析后,部分设备仍然可能访问旧 IP。
3.5 DNS 常见资源记录类型
| 类型 | 作用 | 示例 |
|---|---|---|
| A | 指向 IPv4 地址 | 192.0.2.80 |
| AAAA | 指向 IPv6 地址 | 2001:db8::1 |
| NS | 指定权威 DNS 服务器 | ns1.example.com |
| CNAME | 指向另一个域名 | www.example.com |
| MX | 指定邮件服务器 | mail.example.com |
| TXT | 保存文本信息 | SPF 等记录 |
| SOA | DNS 区域管理信息 | Serial、Refresh 等 |
| SRV | 指定某种服务的位置 | 目标主机与端口 |
其中 MX 记录有一个优先级字段。
例如:
dns
example.com. IN MX 10 mail1.example.com.
example.com. IN MX 20 mail2.example.com.
通常数字越小,优先级越高。
3.6 一个 DNS 区域文件实例
dns
$ORIGIN example.com.
$TTL 3600
; SOA:区域管理信息
@ IN SOA ns1.example.com. admin.example.com. (
2026101901
3600
1800
604800
300
)
; 权威 DNS
@ IN NS ns1.example.com.
@ IN NS ns2.example.com.
; IPv4
@ IN A 192.0.2.80
www IN A 192.0.2.80
api IN A 192.0.2.81
mail IN A 192.0.2.25
ns1 IN A 192.0.2.53
ns2 IN A 198.51.100.53
; IPv6
www IN AAAA 2001:db8::1
; 别名
blog IN CNAME www.example.com.
; 邮件服务器
@ IN MX 10 mail.example.com.
; 文本记录
@ IN TXT "v=spf1 mx -all"
; 服务记录
_sip._tcp IN SRV 10 5 5060 sip.example.com.
sip IN A 192.0.2.60
其中 @ 表示当前区域名,即 example.com.。
SOA 记录中的几个数字依次描述区域序列号、刷新间隔、重试间隔、过期时间和与否定缓存有关的参数。
需要注意,这是一份教学用的区域文件,实际部署还需要正确配置委托、glue 记录和可访问的名称服务器。
3.7 DNS 如何保证速度与可靠性?
主要依靠两个机制:
第一:冗余和分布式部署。
同一个区域可以设置多个权威 DNS 服务器,降低单台服务器故障造成的影响。
第二:缓存。
递归 DNS、本机系统甚至浏览器都可能缓存解析结果,减少重复查询。
因此,DNS 的整体设计思路是:
层次化管理解决规模问题,分布式部署改善可用性,缓存提高查询效率。
3.8 Linux 下进行 DNS 实验
Ubuntu 上可以安装:
bash
sudo apt install dnsutils
查询 A 记录:
bash
dig example.com A
查询 MX 记录:
bash
dig example.com MX
观察逐级查询:
bash
dig +trace www.example.com
其中 +trace 可以帮助我们观察从根区域逐步查找权威信息的过程。
四、Email:电子邮件系统的工作原理
电子邮件看起来只是点击发送按钮,但其背后涉及多个应用层协议。
最重要的包括:
- SMTP
- MIME
- POP3
- IMAP
4.1 一封邮件如何到达对方?
假设 Alice 给 Bob 发送邮件。
整个过程可以抽象为:
text
Alice 邮件客户端
│
│ SMTP
▼
Alice 邮件服务器
│
│ SMTP
▼
Bob 邮件服务器
│
│ POP3 / IMAP
▼
Bob 邮件客户端
这个过程中,发送方不需要知道 Bob 的电脑在哪里。
邮件通常先到达 Bob 的邮件服务器,并存储在他的邮箱中。
Bob 可以之后再登录邮箱读取邮件。
这就实现了异步通信:收件人不必在发件人发送时保持在线。
4.2 SMTP:发送邮件
SMTP(Simple Mail Transfer Protocol),即简单邮件传输协议。
它使用 TCP 进行通信,采用命令---响应交互。
常见 SMTP 端口包括:
| 端口 | 典型用途 |
|---|---|
| 25 | 邮件服务器之间传输 |
| 587 | 邮件客户端提交邮件,通常通过 STARTTLS 加密 |
| 465 | 使用隐式 TLS 的邮件提交 |
教材中的 SMTP 通常指基于 TCP 25 端口的服务器间传输。
其交互过程可以简化为:
text
客户端 服务器
│ │
│ ─── TCP 建立连接 ───→ │
│ │
│ ←── 220 Ready ─────── │
│ │
│ ─── EHLO ───────────→ │
│ ←── 250 OK ────────── │
│ │
│ ─── MAIL FROM ──────→ │
│ ←── 250 OK ────────── │
│ │
│ ─── RCPT TO ────────→ │
│ ←── 250 OK ────────── │
│ │
│ ─── DATA ───────────→ │
│ ←── 354 ───────────── │
│ │
│ ─── 邮件内容 ───────→ │
│ ←── 250 OK ────────── │
│ │
│ ─── QUIT ───────────→ │
│ ←── 221 Bye ───────── │
SMTP 使用文本命令,服务器通过状态码和说明文本回应客户端。
例如:
smtp
EHLO client.example.com
MAIL FROM:<alice@example.com>
RCPT TO:<bob@example.net>
DATA
From: alice@example.com
To: bob@example.net
Subject: Hello
Hello Bob!
.
QUIT
这里省略了实际 SMTP 服务器回复以及可能需要的认证、TLS 协商步骤。
其中,MAIL FROM 与 RCPT TO 指定 SMTP 信封信息,而正文头部的 From、To 是邮件消息自身的字段,二者并不完全相同。
4.3 MIME:为什么邮件能够携带图片、文件?
传统电子邮件格式主要面向文本。
如果需要传输:
- 中文
- 图片
- 音频
- 视频
- HTML 内容
就必须能够说明这些数据的类型、编码和组织结构。
MIME(Multipurpose Internet Mail Extensions)便是为此设计的一组扩展标准。
需要特别注意:
MIME 不是负责在服务器之间传输邮件的独立协议,而是描述邮件内容格式与编码的标准。
常见 MIME 字段如下:
| 字段 | 作用 |
|---|---|
| MIME-Version | MIME 版本 |
| Content-Type | 内容类型 |
| Content-Transfer-Encoding | 内容传输编码 |
| Content-ID | 内容标识 |
| Content-Description | 内容描述 |
例如:
text
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: base64
其中:
text
text/plain
说明内容是纯文本。
text
charset=UTF-8
指定字符集。
text
base64
表示内容经过 Base64 编码。
需要注意,Base64 是一种编码方式,不是加密算法。
如果一封邮件包含多个部分,可以使用:
text
Content-Type: multipart/mixed
将邮件正文和附件组织在同一封邮件中。
所以,SMTP 与 MIME 的关系可以简单理解为:
SMTP 负责邮件的传输交互,MIME 负责邮件内容的组织和表示。
4.4 POP3:从服务器读取邮件
POP3(Post Office Protocol Version 3)主要用于从邮件服务器获取邮件。
常用端口:
text
TCP 110
TCP 995(隐式 TLS)
它支持读取、下载以及删除邮件等操作。
传统 POP3 的设计相对简单,偏向客户端获取服务器上的邮件。
不过,并不是使用 POP3 就一定会删除服务器上的邮件,客户端也可以配置保留副本。
4.5 IMAP:管理服务器上的邮件
IMAP(Internet Message Access Protocol)提供更丰富的邮件访问和管理能力。
常见端口:
text
TCP 143
TCP 993(隐式 TLS)
例如:
用户在手机上将一封邮件标记为已读。
之后打开电脑,在同一个邮箱中也能看到这封邮件的状态。
这得益于 IMAP 对服务器端邮件状态和邮箱管理的支持。
IMAP 可以支持:
- 查询服务器上的邮件。
- 管理邮件文件夹。
- 标记已读、未读。
- 获取部分邮件内容。
- 在多个客户端之间同步服务器端状态。
因此:
| 协议 | 主要职责 |
|---|---|
| SMTP | 发送和转发邮件 |
| MIME | 描述邮件内容格式 |
| POP3 | 获取服务器上的邮件 |
| IMAP | 远程访问和管理邮件 |
另外,电子邮件服务器之间的通信还会用到 DNS。
例如 Alice 给 bob@example.net 发送邮件,发送方的邮件服务器会查询 example.net 的 MX 记录,以确定应该向哪个邮件服务器投递。
这也体现出不同应用层协议之间的协作关系。
五、FTP:文件传输协议
FTP(File Transfer Protocol)是一种基于 TCP 的文件传输协议。
其典型功能包括:
- 上传文件。
- 下载文件。
- 查看目录。
- 删除文件。
- 重命名文件。
FTP 的一个显著特点是:
将控制连接和数据连接分开。
5.1 为什么 FTP 需要两条连接?
考虑这样一个场景。
客户端连接 FTP 服务器后,希望先查看目录,再选择文件下载。
通信中存在两类不同的信息:
第一类:控制信息
例如:
text
登录
查看目录
下载文件
删除文件
第二类:实际传输的数据
例如:
text
文件内容
目录列表
FTP 将这两类信息放在不同的 TCP 连接中传输。
text
FTP 客户端 FTP 服务器
│ │
│──── 控制连接 ──────────│
│ TCP 21 │
│ │
│──── 数据连接 ──────────│
│ 文件数据 │
│ │
控制连接通常在整个 FTP 会话期间保持。
数据连接则根据具体传输操作建立,并在传输完成后关闭。
5.2 控制连接
FTP 服务器通常监听 TCP 21 端口,接收控制连接。
客户端可以发送命令,例如:
text
USER username
PASS password
PWD
CWD /files
LIST
RETR test.txt
STOR upload.txt
QUIT
命令含义分别是:
| 命令 | 作用 |
|---|---|
| USER | 指定用户名 |
| PASS | 输入密码 |
| PWD | 查询当前目录 |
| CWD | 切换目录 |
| LIST | 获取目录列表 |
| RETR | 下载文件 |
| STOR | 上传文件 |
| QUIT | 结束会话 |
服务器收到命令后,会返回数字状态码和相应说明。
例如:
text
220 Service ready
331 Password required
230 User logged in
5.3 数据连接与主动模式
教材常说:
text
FTP 使用 TCP 21/20
但这实际上主要描述传统 FTP 主动模式中的服务器端端口。
在主动模式下:
- 客户端连接服务器的 TCP 21 端口。
- 客户端告诉服务器自己准备接收数据的地址和端口。
- 服务器通常从 TCP 20 端口主动连接客户端指定端口。
- 双方开始传输数据。
示意:
text
客户端 服务器
随机端口 ─── 控制连接 ─────→ TCP 21
指定端口 ←── 数据连接 ───── TCP 20
这里的 TCP 20 通常是服务器主动数据连接的源端口,并不是所有 FTP 数据连接都会使用它。
5.4 被动模式(Passive Mode)
主动模式可能遇到一个问题:
如果客户端处于 NAT 或防火墙后面,服务器主动连接客户端可能失败。
因此,FTP 还支持被动模式。
流程如下:
- 客户端连接服务器的 TCP 21 端口。
- 客户端请求进入被动模式。
- 服务器告知客户端用于数据连接的地址和端口。
- 客户端主动连接服务器的数据端口。
- 开始文件传输。
例如:
text
客户端 服务器
随机端口 ─── 控制连接 ─────→ TCP 21
随机端口 ─── 数据连接 ─────→ 服务器指定端口
所以:
FTP 的控制连接通常使用服务器 TCP 21 端口,但数据连接的端口和发起方向取决于主动或被动模式。
5.5 FTP 为什么逐渐被替代?
传统 FTP 存在一个明显问题:
默认并不对用户名、密码和文件内容进行加密。
因此在不可信网络中直接使用传统 FTP 存在风险。
现代实际部署中常见:
- FTPS:在 FTP 基础上使用 TLS。
- SFTP:通过 SSH 进行文件传输。
需要注意:
SFTP 并不是 FTP 加上 TLS,而是基于 SSH 的另一套文件传输协议。
六、WWW、URL 与 HTTP
最后来看我们最常接触的 Web。
6.1 什么是 WWW?
WWW(World Wide Web),即万维网。
可以将其理解为建立在互联网之上的、通过资源标识符和超链接关联起来的分布式信息系统。
例如,一个网页中包含:
html
<a href="https://www.example.com/about">
关于我们
</a>
用户点击这个链接,就可以访问另一个资源。
网页中的超链接将大量分散在不同服务器上的信息资源连接起来。
因此,WWW 不是某一台服务器,也不是互联网本身。
互联网提供网络基础设施,WWW 则是运行在互联网之上的一种信息服务系统。
6.2 URL 是什么?
URL(Uniform Resource Locator),统一资源定位符。
它用于标识网络资源的位置以及访问方式。
例如:
text
https://www.example.com:443/docs/index.html?id=10
可以拆解为:
text
https
│
└── Scheme:协议方案
www.example.com
│
└── Host:主机名
443
│
└── Port:端口
/docs/index.html
│
└── Path:路径
id=10
│
└── Query:查询参数
完整结构通常可以表示为:
text
scheme://host:port/path?query#fragment
其中端口可以省略,HTTP 和 HTTPS 有相应默认端口。
fragment 表示片段标识符,例如:
text
https://example.com/page.html#section2
在典型网页访问中,片段标识符由客户端用于定位资源内部的位置,通常不会作为 HTTP 请求目标的一部分发送给服务器。
URL 是 URI(统一资源标识符)的一种形式,强调资源的定位方式。
6.3 HTTP 是什么?
HTTP(Hypertext Transfer Protocol),即超文本传输协议。
它是 Web 中最重要的应用层协议之一。
HTTP 采用请求---响应模型:
text
客户端 服务器
│ │
│ ───── HTTP Request ───────→ │
│ │
│ ←──── HTTP Response ─────── │
│ │
客户端发送请求,服务器返回响应。
需要注意,HTTP 并不只能传输 HTML。
它同样可以传输:
- JSON
- 图片
- CSS
- JavaScript
- 视频
- 文件
所以现代 HTTP 已经是非常通用的应用层通信协议。
6.4 HTTP 请求报文
以 HTTP/1.1 为例:
http
GET /index.html HTTP/1.1
Host: www.example.com
Accept: text/html
Connection: keep-alive
HTTP/1.1 请求通常可以分为:
text
请求行
请求头字段
空行
请求体(可选)
请求行:
http
GET /index.html HTTP/1.1
包含:
GET:请求方法。/index.html:请求目标。HTTP/1.1:协议版本。
头字段提供额外信息,例如 Host 表示目标主机,Accept 表示客户端希望接收的媒体类型。
6.5 HTTP 常见请求方法
| 方法 | 主要用途 |
|---|---|
| GET | 获取资源 |
| POST | 提交数据,由目标资源按定义处理 |
| PUT | 创建或替换目标资源的表示 |
| DELETE | 请求删除目标资源 |
| HEAD | 获取响应元数据,不返回响应正文 |
| OPTIONS | 查询目标支持的通信选项 |
| PATCH | 对资源进行部分修改 |
例如:
GET 请求:
http
GET /users/1 HTTP/1.1
Host: api.example.com
POST 请求:
http
POST /users HTTP/1.1
Host: api.example.com
Content-Type: application/json
Content-Length: 16
{"name":"Alice"}
GET 和 POST 最主要的区别不是参数放在 URL 还是请求体中,而是它们在 HTTP 中规定的语义不同。
GET 属于安全方法,设计目的在于获取资源;POST 则用于提交需要由服务器处理的数据。
6.6 HTTP 响应报文
服务器接收到请求后,会返回 HTTP 响应。
例如:
http
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 45
<html><body><h1>Hello!</h1></body></html>
HTTP/1.1 响应一般包含:
text
状态行
响应头字段
空行
响应体(可选)
状态行:
http
HTTP/1.1 200 OK
其中 200 是 HTTP 状态码,表示请求成功。
6.7 HTTP 状态码
HTTP 状态码按照首位数字分为五类。
| 类别 | 含义 | 典型状态码 |
|---|---|---|
| 1xx | 信息性响应 | 100 Continue |
| 2xx | 成功 | 200 OK、201 Created |
| 3xx | 重定向 | 301 Moved Permanently、302 Found |
| 4xx | 客户端错误 | 400 Bad Request、403 Forbidden、404 Not Found |
| 5xx | 服务器错误 | 500 Internal Server Error、503 Service Unavailable |
例如:
text
200:请求成功
301:资源被永久重定向
403:服务器拒绝请求
404:目标资源未找到
500:服务器内部错误
503:服务暂时不可用
这样,客户端便可以根据状态码判断服务器的处理结果。
6.8 HTTP 为什么说是无状态协议?
HTTP 的一个重要特点是:
HTTP 是无状态协议(Stateless Protocol)。
这里的无状态,不是指服务器不能存储任何信息。
而是指:
HTTP 协议本身不要求服务器为了处理下一次请求而记住上一次请求的应用状态。
例如:
text
第一次请求:
GET /home
第二次请求:
GET /profile
从 HTTP 协议本身来看,这两次请求是相互独立的。
但现实中用户登录网站后,服务器当然能够识别用户身份。
这又是如何实现的?
常见方式包括 Cookie 和服务器端 Session。
例如:
text
用户登录
│
▼
服务器建立登录状态
│
▼
客户端保存 Cookie
│
▼
后续请求携带 Cookie
│
▼
服务器识别用户会话
所以:
HTTP 无状态不意味着 Web 应用不能维护状态。
应用可以利用 Cookie、Session、Token 等机制实现状态关联。
另外,HTTP 的无状态与 TCP 连接是否持续存在,是两个不同概念。
6.9 HTTP 持续连接与非持续连接
考虑这样一个网页:
text
index.html
style.css
main.js
logo.png
浏览器需要获取多个资源。
如果每次请求都重新建立 TCP 连接,会产生额外的连接建立开销。
因此可以区分两种通信方式。
非持续连接:
text
建立 TCP 连接
请求 HTML
接收 HTML
关闭连接
建立 TCP 连接
请求 CSS
接收 CSS
关闭连接
每次重新建立连接会产生额外的 RTT 和资源开销。
持续连接:
text
建立 TCP 连接
│
请求 HTML
│
接收 HTML
│
请求 CSS
│
接收 CSS
│
请求 JS
│
接收 JS
│
复用同一条连接
HTTP/1.1 默认支持持续连接,除非通过相应机制关闭或连接出现其他终止条件。
这就可以减少重复建立 TCP 连接的成本。
6.10 HTTP/1.1 流水线与非流水线
即使使用持续连接,也有不同的请求发送方式。
非流水线:
客户端先发送一个请求,等待对应响应,再发送下一个请求。
text
请求 A ────────→
←────── 响应 A
请求 B ────────→
←────── 响应 B
流水线(Pipelining):
客户端可以连续发送多个请求,不必等到前一个响应到达才发送下一个。
text
请求 A ────────→
请求 B ────────→
请求 C ────────→
←────── 响应 A
←────── 响应 B
←────── 响应 C
HTTP/1.1 流水线仍然要求服务器按照请求顺序发送对应响应,因此容易受到队头阻塞等问题的影响。
现实中 HTTP/1.1 流水线没有得到广泛采用,浏览器更常使用其他策略,而后来的 HTTP/2 引入了多路复用。
6.11 HTTP、HTTPS、HTTP/2 与 HTTP/3
教材中常说:
text
HTTP 使用 TCP,端口 80。
这是传统 HTTP/1.1 等场景下的典型情况。
现代 Web 已经发展出多种版本与传输方式。
| 协议 | 典型底层传输 | 默认端口 | 主要特点 |
|---|---|---|---|
| HTTP/1.1 | TCP | 80(HTTP) | 持续连接 |
| HTTPS(HTTP/1.1) | TLS over TCP | 443 | 加密 HTTP 通信 |
| HTTP/2 | 通常 TLS over TCP | 443 | 多路复用、二进制分帧、头部压缩 |
| HTTP/3 | QUIC over UDP | 443 | QUIC 流、多路复用,减少跨流队头阻塞 |
需要注意,HTTP/2 也可以在特定环境下不使用 TLS,因此表中描述的是常见 Web 部署方式。
HTTPS 并不是一种完全独立于 HTTP 的应用语义协议,而是利用 TLS 保护 HTTP 通信。
HTTP/3 则不再直接依赖 TCP,而是使用 QUIC。
所以,不能简单地认为所有 HTTP 都必须基于 TCP。
七、综合实例:浏览器输入网址后发生了什么?
现在我们把前面学到的内容串联起来。
假设用户输入:
text
https://www.example.com/index.html
第一步:解析 URL
浏览器识别出:
text
协议方案:https
域名:www.example.com
端口:443(默认)
路径:/index.html
第二步:DNS 域名解析
浏览器需要获得目标域名的可用 IP 地址。
系统可能使用本机缓存,也可能向递归 DNS 查询。
如果需要完整逐级查询,递归 DNS 会沿 DNS 委托关系查找权威记录。
最终获取目标地址。
第三步:建立传输连接
如果使用 HTTP/1.1 或 HTTP/2,通常通过 TCP 建立连接,再使用 TLS 建立安全通信。
如果使用 HTTP/3,则通常通过 QUIC 建立安全连接。
第四步:发送 HTTP 请求
例如:
http
GET /index.html HTTP/1.1
Host: www.example.com
浏览器告诉服务器自己希望获取 /index.html 资源。
第五步:服务器处理请求
服务器根据请求找到相应的资源,或将请求交给后端应用处理。
然后构造 HTTP 响应。
例如:
http
HTTP/1.1 200 OK
Content-Type: text/html
<html>...</html>
第六步:浏览器处理内容
浏览器解析 HTML,发现其中可能还包含:
html
<link rel="stylesheet" href="/style.css">
<script src="/main.js"></script>
<img src="/logo.png">
这些资源也需要被获取。
浏览器会根据缓存情况、资源地址、协议版本等决定后续请求的方式。
在资源获取和解析过程中,浏览器逐步构建和渲染页面,最终呈现用户看到的网站。
于是我们发现:
一个看似简单的打开网页操作,实际上涉及多个层次、多个协议和多个服务之间的配合。
八、应用层协议对比总结
| 协议 | 核心功能 | 常见端口/传输 |
|---|---|---|
| DNS | 域名及其他 DNS 资源记录查询 | UDP/TCP 53 |
| SMTP | 邮件发送与转发 | TCP 25、587、465 |
| POP3 | 邮件访问与下载 | TCP 110、995 |
| IMAP | 邮件访问与管理 | TCP 143、993 |
| FTP | 文件传输 | TCP 21 控制连接;数据端口依模式决定 |
| HTTP/1.1 | Web 资源请求与响应 | 通常 TCP 80 |
| HTTPS | 受 TLS 保护的 HTTP 通信 | 通常 TCP 443,HTTP/3 通常 UDP 443 |
MIME 没有独立的传输端口,因为它主要是一套消息内容格式标准,而不是独立建立网络连接的协议。
九、结语
回到最初的问题:既然计算机网络已经有了 TCP、UDP 和 IP,为什么还需要应用层?
因为下层协议解决的是通用的通信问题,而应用层要解决的是通信到底为了完成什么任务。
用户发送邮件,并不关心邮件经过了多少台路由器,而是希望邮件能够正确地送达收件人的邮箱。
用户访问网页,并不关心 TCP 数据被拆分为多少个报文段,而是希望服务器能够理解请求,并返回正确的网页内容。
应用层就是建立在这些底层通信能力之上的一层抽象。
不同应用又根据自身需求制定了不同的通信规则:
- DNS 负责把域名等名称信息组织起来,并提供分布式查询。
- SMTP 配合 MIME 完成电子邮件的传输与内容表示。
- POP3 和 IMAP 帮助用户访问邮箱。
- FTP 将控制命令与文件数据分开传输。
- HTTP 通过请求和响应实现 Web 资源的访问。
它们虽然服务于不同需求,但遵循着同一个基本思想:
底层网络负责让信息能够被传送,应用层协议负责让通信双方理解信息并完成具体任务。
这正是计算机网络分层架构的价值。