Android 网络协议全解析:从 TCP 三次握手到 HTTPS 加密,一篇就够了
面试问网络,永远绕不开这几个问题:三次握手为什么是三次?四次挥手为什么是四次?TCP 和 UDP 什么区别?HTTP/1.1、HTTP/2、HTTP/3 演进逻辑?HTTPS 怎么加密的? 这篇按"分层模型 → 传输层 → 应用层 → 安全层"的顺序,一条线讲透,建议收藏。
引言
网络知识是分层嵌套的:不理解 TCP 三次握手,就不知道为什么 HTTP/2 的多路复用还有队头阻塞;不理解 HTTP/1.x 的痛点,就不知道 HTTP/2 在解决什么;不理解对称/非对称加密,就看不懂 HTTPS 握手在干嘛。
所以这篇从最底层的分层模型讲起,一路走到 HTTPS,最后用"一次完整网络请求"收尾。读完这篇,面试网络题基本全覆盖。
一、网络分层模型:为什么要有层
1.1 为什么分层
- 网络不稳定,需要分块传输:把大块数据拆成小包,出错只重传坏的那块
- 高内聚、低耦合:每层只管自己的事,改某一层不影响其他层
1.2 四层 / 五层 / 七层
| 模型 | 分层 | 说明 |
|---|---|---|
| OSI 七层(学术界) | 应用层、表示层、会话层、传输层、网络层、数据链路层、物理层 | 分得细、实现复杂、学术价值大 |
| TCP/IP 四层(工业界) | 应用层、传输层、网络层、数据链路层 | OSI 的简化版,实际使用 |
| 五层模型(教学常用) | 应用层、传输层、网络层、数据链路层、物理层 | 四层 + 物理层 |
1.3 五层模型各层职责
| 层 | 职责 | 协议/单位 |
|---|---|---|
| 应用层 | 为特定应用提供数据传输服务 | HTTP、DNS(单位:报文) |
| 传输层 | 为进程提供通用数据传输服务 | TCP、UDP(单位:报文段/用户数据报) |
| 网络层 | 为主机提供数据传输服务(寻址) | IP(单位:分组) |
| 数据链路层 | 为同一链路的主机提供服务 | 以太网、WiFi(单位:帧) |
| 物理层 | 在传输媒体上传输比特流 | (单位:比特) |
记忆锚点:应用层管"内容",传输层管"进程到进程",网络层管"主机到主机",链路层管"一跳一跳"。
1.4 数据是怎么传输的:层层封装
网络通信本质是二进制数据流,靠层层封装传递:
markdown
HTTP 报文(应用层)
↓ 添加 TCP 头(源端口 + 目的端口)
TCP 数据包(传输层)
↓ 添加 IP 头(源 IP + 目的 IP)
IP 数据包(网络层)
↓ 添加以太网头
以太网帧(数据链路层)
↓ 二进制比特流
物理媒体传输
每层只认识自己的头:发送方逐层"加头"(封装),接收方逐层"去头"(解封装)。
二、TCP vs UDP:传输层的两兄弟
| TCP | UDP | |
|---|---|---|
| 连接 | 面向连接(1 对 1,先握手) | 无连接(可 1 对多) |
| 可靠性 | 可靠(超时重传、应答机制、分段传输) | 不可靠(丢了不管) |
| 有序性 | 保证顺序 | 不保证 |
| 传输方式 | 字节流 | 数据报 |
| 特点 | 慢但稳 | 快但裸 |
| 典型应用 | HTTP、文件传输 | DNS、视频通话、游戏、QUIC |
TCP 的四大能力:
| 能力 | 说明 |
|---|---|
| 面向连接 | 三次握手建立,四次挥手关闭 |
| 可靠性 | 应答机制 + 超时重传(按 RTT 动态计算重传时间)+ 分割传输 |
| 流量控制 | 滑动窗口,避免发送过快导致接收方来不及处理而丢包 |
| 拥塞控制 | 根据网络负载调节发送速率:慢开始、拥塞避免、快重传、快恢复 |
流量控制 vs 拥塞控制(高频):
| 流量控制 | 拥塞控制 | |
|---|---|---|
| 作用对象 | 端到端(发送方 ↔ 接收方) | 整个网络 |
| 目的 | 确保接收方来得及接收处理 | 防止网络负载过大导致性能下降 |
| 手段 | 滑动窗口 | 慢开始、拥塞避免、快重传、快恢复 |
记忆锚点:流量控制是"别把对方撑死",拥塞控制是"别把网络堵死"。
三、TCP 三次握手(面试必背)
3.1 详细流程
ini
客户端 服务端
│ ① SYN=1, seq=J(随机数) │ 客户端 → 已发送状态
│ ─────────────────────────────────► │
│ │ 服务端 → 已接收状态
│ ② SYN=1, ACK=1, ack=J+1, seq=K │
│ ◄───────────────────────────────── │
│ ③ ACK=1, ack=K+1 │ 客户端 → 已连接状态
│ ─────────────────────────────────► │ 服务端 → 已连接状态
│ 连接建立完成 │
- SYN(synchronize):请求同步,表示"我想建立连接"
- ACK(acknowledgement):确认,表示"收到你的请求"
3.2 为什么是三次而不是两次
从能力确认角度(面试标准答案):
| 握手 | 确认了谁的能力 |
|---|---|
| 第一次:客户端发包,服务端收到 | 服务端确认:客户端能发、服务端能收 |
| 第二次:服务端发包,客户端收到 | 客户端确认:服务端能收能发、客户端能发能收(但服务端此时还不能确认客户端能收) |
| 第三次:客户端发包,服务端收到 | 服务端确认:客户端能收,双方收发能力全部确认 |
从防攻击角度:两次握手会让"过期的连接请求"(网络延迟后突然到达的旧 SYN)被服务端误认为是新连接,从而建立错误连接、浪费资源。第三次握手让服务端能确认"客户端确实想要连接"。
四、TCP 四次挥手(面试必背)
4.1 详细流程
ini
客户端 服务端
│ ① FIN=1, seq=M │ 客户端 → FIN_WAIT_1(我不发了)
│ ─────────────────────────────────► │
│ ② ACK=1, ack=M+1 │ 服务端 → CLOSE_WAIT(知道了,我还有事)
│ ◄───────────────────────────────── │ 客户端 → FIN_WAIT_2
│ │ (服务端处理剩余任务...)
│ ③ FIN=1, seq=N │ 服务端处理完 → LAST_ACK(我也不发了)
│ ◄───────────────────────────────── │
│ ④ ACK=1, ack=N+1 │ 服务端收到 → 关闭连接
│ ─────────────────────────────────► │ 客户端 → TIME_WAIT,等 2MSL 后关闭
MSL(Maximum Segment Lifetime):报文在网络上存活的最大时间。
TIME_WAIT 为什么等 2MSL:
- 防止最后一个 ACK 丢失,服务端重发 FIN 时客户端还能回应
- 让旧连接的报文在网络中彻底消失,避免污染新连接
4.2 为什么是四次而不是三次
因为 TCP 是全双工 模式,连接的两个方向要分别关闭:
- 客户端发 FIN 只代表"我发完了",不代表"服务端也发完了"
- 服务端收到 FIN 后先回 ACK(知道了),但可能还有数据要发,所以不能立刻回 FIN
- 等服务端数据发完,再发自己的 FIN------ACK 和 FIN 必须分两次
对比三次握手:建立连接时服务端收到 SYN 后可以直接同时回 SYN+ACK(不需要等待任何东西),所以能合成一次。这就是"握手三次、挥手四次"的根本原因。
五、HTTP:应用层的核心协议
5.1 HTTP 是什么
超文本传输协议(HyperText Transfer Protocol) 。两种直观印象:浏览器打开网页;Android 发网络请求拿数据。本质是请求-响应模型,跑在 TCP 之上,无状态。
5.2 HTTP 报文
请求:请求行(方法 + 路径 + 版本)+ 请求头 + 空行 + 请求体
响应:状态行(版本 + 状态码 + 原因短语)+ 响应头 + 空行 + 响应体
5.3 状态码
| 范围 | 含义 | 例子 |
|---|---|---|
| 1xx | 临时性消息 | 100 Continue |
| 2xx | 成功 | 200 OK |
| 3xx | 重定向 | 301 永久、302 临时、304 缓存未修改 |
| 4xx | 客户端错误 | 400 参数错、401 未认证、403 禁止、404 不存在 |
| 5xx | 服务端错误 | 500 服务器错、502 网关错、503 不可用 |
5.4 登录授权:Cookie / Authorization / Token
Cookie :服务端不想把信息存在服务端,于是发给客户端,让客户端自动存储、自动重新发送。
| Cookie 作用 | 说明 |
|---|---|
| 会话管理 | 登录状态、购物车 |
| 个性化设置 | 用户偏好、主题 |
| 用户行为分析 | 埋点统计 |
Authorization 两种常见方式:
| 方式 | 原理 | 注意 |
|---|---|---|
| Basic | 用户名密码 Base64 后传给服务端 | 必须配 HTTPS,否则等于明文 |
| Bearer | 携带 Token(如 OAuth2 流程) | 微信登录就是 OAuth2,刷新时用 refresh token 换新 token |
灵魂拷问:Cookie / Session / Token 区别?
| 存哪 | 本质 | |
|---|---|---|
| Cookie | 客户端 | 服务端发给客户端,客户端自动保存自动发送 |
| Session | 服务端 | 连接建立后服务端临时保存用户信息 |
| Token | 客户端 | 令牌,把 uid、时间戳等签名后放请求头,服务端验签确认身份 |
六、HTTP 版本演进:1.x → 2 → 3
6.1 HTTP/1.0 → HTTP/1.1
| 特性 | HTTP/1.0 | HTTP/1.1 |
|---|---|---|
| 连接 | 短连接,每次请求新建 TCP | 持久连接 keep-alive |
| Host 头 | 无 | 必须有(一台服务器多域名) |
| 缓存 | Expires | Cache-Control、ETag、If-Modified-Since |
HTTP/1.x 的三大痛点:
- 队头阻塞:一个连接上响应必须按请求顺序返回,前一个慢后面全排队
- 半双工:同一时刻一个连接只能有一个请求在飞(靠浏览器开 6 个连接缓解)
- 头部冗余:每次请求重复传大头部,不压缩
6.2 HTTP/2:解决 1.x 的痛点
| 特性 | 作用 |
|---|---|
| 二进制分帧 | 报文拆成带 Stream ID 的帧 |
| 多路复用 | 一个 TCP 连接并发多个流,帧交错传输,靠 Stream ID 重组 |
| HPACK 头部压缩 | 静态表 + 动态表 + 哈夫曼,头部减 80%+ |
| 服务器推送 | 服务器主动推资源(已被主流浏览器废弃) |
遗留问题 :多路复用建立在一个 TCP 连接 上,TCP 是"有序字节流"------一个包丢了,整个连接等重传 ,这就是 TCP 层队头阻塞。
6.3 HTTP/3:换掉 TCP
HTTP/3 = HTTP + QUIC + UDP。QUIC 在 UDP 上自己实现可靠传输:
| 特性 | 说明 |
|---|---|
| 多流独立 | 每个流独立确认、独立重传,彻底解决队头阻塞 |
| 1-RTT / 0-RTT 握手 | 首次 1-RTT,重连 0-RTT(对比 HTTPS 传统 3-RTT) |
| 连接迁移 | 用 Connection ID 标识连接,WiFi 切 4G 不断连 |
| TLS 1.3 内建 | 加密是协议默认 |
6.4 三版本对比总表
| HTTP/1.1 | HTTP/2 | HTTP/3 | |
|---|---|---|---|
| 传输层 | TCP | TCP | UDP + QUIC |
| 并发 | 6 连接 | 1 连接多路复用 | 1 连接多路复用 |
| 队头阻塞 | 应用层有 | TCP 层有 | 彻底解决 |
| 握手 | 1-RTT | 1-RTT | 1-RTT / 0-RTT |
七、加密基础:对称 vs 非对称
7.1 对称加密
加密解密用同一个密钥:AES(主流)、DES(已淘汰)。
| 优点 | 缺点 |
|---|---|
| 快,适合大量数据 | 密钥分发难:密钥怎么安全地给对方? |
7.2 非对称加密
一对密钥:公钥 + 私钥。公钥加密私钥解,私钥签名公钥验。RSA(经典)、ECC/ECDHE(现代主流)。
| 优点 | 缺点 |
|---|---|
| 解决密钥分发:公钥随便传 | 慢,不适合加密大量数据 |
7.3 哈希与数字签名
- 哈希(SHA-256):不可逆,防篡改(改一个字节哈希全变)
- 数字签名 :私钥签名 + 公钥验签 = 身份认证 + 完整性(防冒充 + 防篡改)
7.4 混合加密(HTTPS 实际方案)
arduino
① 非对称加密"协商对称密钥"(慢但安全,只跑一次)
② 对称加密"传输数据"(快,量大)
非对称管密钥协商,对称管数据加密------HTTPS 的骨架。
八、HTTPS:HTTP + TLS
8.1 HTTP vs HTTPS
ini
HTTP = 明文:可被窃听、篡改、冒充
HTTPS = HTTP + TLS:TCP 之上加一层安全协议
HTTPS 解决三件事:加密(防窃听)、认证(防冒充)、完整性(防篡改)。
8.2 TLS 握手流程(面试必背)
客户端 服务器
│ ① ClientHello(TLS版本 + 支持算法 + 客户端随机数) │
│ ───────────────────────────────────────► │
│ ② ServerHello(选定算法 + 服务器随机数) │
│ ③ Certificate(三级证书 + 公钥) │
│ ◄─────────────────────────────────────── │
│ ④ 验证证书(根证书验证,信任后) │
│ ⑤ ClientKeyExchange │
│ 生成随机数 → 公钥加密 → 得到 secret │
│ (唯一一次非对称加密传输) │
│ ───────────────────────────────────────► │
│ ⑥ 双方用 secret 开始对称加密通信 │
│ ◄─────────────────────────────────────── │
握手里的三个随机数:
| 随机数 | 保密吗 | 作用 |
|---|---|---|
| 客户端随机数 | 明文 | 防重放 |
| 服务器随机数 | 明文 | 防重放 |
| 预主密钥(secret) | 公钥加密 | 真正的机密,派生会话密钥 |
类似"加盐"思路,术语叫 nonce:防重放 + 保证每次会话密钥唯一。
8.3 证书的作用:为什么 HTTPS 需要它
先澄清一个常见误解:CA 签名的是证书,不是数据包。
证书解决的第一个问题:非对称加密里,客户端要用"服务器公钥"加密密钥------但怎么确认这个公钥真的是服务器的,而不是中间人伪造的?
证书 = 服务器公钥 + 身份信息 + CA 的数字签名,它的作用分三层:
| 作用 | 说明 |
|---|---|
| 防冒充(身份认证) | 证明"我就是这个域名",公钥确实属于对面服务器 |
| 防篡改(完整性) | 证书内容被改,签名校验失败 |
| 建立信任链 | 通过 CA 签名,把"陌生服务器"和"系统预装的根 CA"连起来 |
CA 签名 vs 数据包保护,是两码事:
- CA 在签发证书时用自己私钥给证书签一次名(一次性,提前做好),证明证书可信
- 每次通信的数据包 靠握手协商出的会话密钥保护(加密 + MAC 校验),跟 CA 无关
- CA 的使命在握手验证证书后即结束,之后全是会话密钥的事
三个密钥各司其职(面试易混):
| 密钥 | 用途 |
|---|---|
| CA 的私钥 | 给证书签名(防伪造) |
| 上级证书的公钥 | 验证下级证书签名(验可信) |
| 服务器证书里的公钥 | 加密预主密钥(建安全通道) |
记忆口诀:签名用私钥,验签用公钥,证书里的公钥用来加密密钥。
8.4 为什么是三级证书
证书是三层结构,不是只有一张:
swift
┌─────────────────────────────────┐
│ 根证书(Root CA) │ ← 自签名,预装在系统/浏览器信任库
│ 如:DigiCert Global Root G2 │ 绝对信任的起点
└──────────────┬──────────────────┘
│ 用根私钥签发
▼
┌─────────────────────────────────┐
│ 中间证书(Intermediate CA) │ ← 由根签发,日常签发工作由它干
└──────────────┬──────────────────┘
│ 用中间私钥签发
▼
┌─────────────────────────────────┐
│ 服务器证书(Server/Leaf) │ ← 真正的"网站身份证"
│ 如:www.example.com │ 含域名 + 公钥 + 有效期
└─────────────────────────────────┘
| 层级 | 谁签发 | 在哪 | 作用 |
|---|---|---|---|
| 根证书 | 自己签自己(自签名) | 预装在系统信任库 | 信任链的锚点 |
| 中间证书 | 根证书 | 服务器发给客户端 | 转发信任,签发服务器证书 |
| 服务器证书 | 中间证书 | 服务器发给客户端 | 证明"我就是这个域名" |
关键细节:
- 服务器握手时只发两张 :服务器证书 + 中间证书,不发根证书(客户端系统里已有)
- 验证自下而上:叶子 → 中间 → 根,最后在系统信任库找到根 → 信任链闭合
- 根证书凭什么信?靠"预装"------操作系统/浏览器出厂就内置根证书,不需要网络验证
为什么必须要有中间层(三级)? 这是安全设计,三个原因:
- 保护根私钥(最重要) :根私钥一旦泄露,攻击者能伪造任何网站。所以根私钥离线保存在保险柜里,平时根本不碰;日常签发全由中间 CA 干
- 泄露可隔离 :万一中间私钥泄露,只需吊销中间证书,根证书和整个信任体系不用动
- 分类管理:不同中间 CA 对应不同类型证书(OV/EV/通配符),方便管理、区分、审计
为什么不是两级(根直接签服务器证书)?因为那样根私钥就要天天拿出来干活,暴露面大、一旦泄露全盘皆输。中间层就是根和业务之间的"缓冲区"。
真实例子(浏览器地址栏锁 → 证书):
markdown
根:GlobalSign Root CA
└─ 中间:GlobalSign RSA OV SSL CA 2018
└─ 叶子:baidu.com
8.5 中间人攻击(MITM)
客户端 ──► 中间人 ◄──► 服务器
中间人劫持客户端的握手请求,客户端不知道被劫持,与中间人建立了连接;中间人又冒充客户端与服务器建立连接------整个链路对中间人透明。
如何防御(Android 实践):
- 下载服务器证书,内置到 assets 文件夹,客户端只信任内置证书(SSL Pinning 证书校验)
- 可以内置多个证书防过期,只要有一个通过校验即可
- 配合 HTTPS + 证书校验,中间人无法伪造(伪造需要 CA 证书,而客户端不信任除内置外的任何 CA)
九、一次完整网络请求(终极串讲)
css
① DNS 解析:域名 → IP(浏览器缓存 → hosts → 本地 DNS → 各级 DNS)
② TCP 三次握手:建立连接(1-RTT)
③ TLS 握手(HTTPS):验证证书 + 协商密钥(多 1~2 RTT)
④ 发送 HTTP 请求(HTTP/2 多路复用 / HTTP/3 QUIC)
⑤ 服务器处理(反向代理 → 业务代码 → 数据库)→ 返回响应
⑥ 浏览器解析渲染(HTML/CSS/JS,过程中再发资源请求)
⑦ 连接复用(keep-alive)或四次挥手关闭
Android 网络优化手段对照:
| 手段 | 对应知识点 |
|---|---|
| HTTPDNS | 绕开 DNS 劫持 |
| 连接池复用 | 省 TCP 三次握手 |
| HTTPS 会话复用 | 省 TLS 握手 |
| 证书内置校验 | 防中间人攻击 |
十、高频面试题速答
Q1:三次握手为什么不是两次? 两次只能确认"服务端能收、客户端能发",无法确认客户端能收;且无法防止过期 SYN 建立错误连接。
Q2:四次挥手为什么不是三次? TCP 全双工,FIN 只代表一方发完;服务端可能还有数据,所以 ACK 和 FIN 分两次发。
Q3:TCP 和 UDP 区别? TCP 面向连接、可靠(重传/应答/分段)、有序、有流量控制和拥塞控制;UDP 无连接、不可靠、快。TCP 保完整,UDP 保及时。
Q4:流量控制和拥塞控制区别? 流量控制端到端(别撑死接收方),拥塞控制全局(别堵死网络)。
Q5:HTTP/1.1、2、3 区别? 1.1 有队头阻塞;2 用多路复用解决应用层队头阻塞,但 TCP 层还有;3 用 QUIC(UDP)彻底解决。
Q6:HTTPS 怎么保证安全? 证书验证身份(防冒充)→ 非对称加密协商密钥 → 对称加密传输(防窃听)→ 哈希校验(防篡改)。
Q7:中间人攻击怎么防? 证书校验(SSL Pinning):把服务器证书内置到 App,不信任系统 CA 之外任何证书。
Q8:对称和非对称加密区别? 对称一个密钥加解密、快、密钥分发难;非对称公钥/私钥、安全分发、慢。HTTPS 两者都用。
结语
把整条线串起来:网络分层(封装思想)→ TCP/UDP(传输)→ 三次握手四次挥手(连接管理)→ HTTP 演进(应用层)→ 加密(安全基础)→ HTTPS + 证书(安全落地)→ 完整请求(全流程)。
下次面试官从任意一点切入,你都能往上往下延伸------这就是网络知识"成体系"的样子。
(本文综合网络协议标准与面试高频考点整理,HTTP/3 部分以 QUIC 最新实现为准。)