本文覆盖 OSI 与 TCP/IP 分层模型对比、IP 协议基础、TCP 三次握手/四次挥手完整状态机、TCP 可靠性机制(序号/确认/重传/滑动窗口/流量控制/拥塞控制),以及 UDP 特性与 TCP/UDP 选型。
目录
| 章节 | 说明 |
|---|---|
| OSI vs TCP/IP 分层模型 | 两种模型对比 |
| IP 协议 | 子网划分、路由、CIDR |
| TCP 三次握手 | 每步状态与原因 |
| TCP 四次挥手 | 每步状态与 TIME_WAIT 原因 |
| TCP 可靠性机制 | 序号/确认/重传/滑动窗口/流量控制/拥塞控制 |
| UDP 特性与适用场景 | UDP 核心特性 |
| TCP vs UDP 选型 | 选型对比表 |
OSI vs TCP/IP 分层模型
| 层次 | OSI 7 层 | TCP/IP 4 层 | 代表协议 |
|---|---|---|---|
| 7 | 应用层 | 应用层 | HTTP、HTTPS、DNS、FTP |
| 6 | 表示层 | 应用层 | TLS/SSL |
| 5 | 会话层 | 应用层 | — |
| 4 | 传输层 | 传输层 | TCP、UDP |
| 3 | 网络层 | 网络层 | IP、ICMP、ARP |
| 2 | 数据链路层 | 网络接口层 | Ethernet、Wi-Fi |
| 1 | 物理层 | 网络接口层 | 网线、光纤 |
核心原则:只要是在网络上跑的包,都是完整的。可以有下层没上层,绝对不可能有上层没下层。每一层的数据在发送时向下封装头部,接收时向上剥离头部。
二层/三层设备的本质:都是运行在其上的程序不同。二层设备(交换机)只摘 MAC 头,三层设备(路由器)摘 MAC 头再摘 IP 头,HTTP 包经过二层设备时,二层设备收到的是包含所有层的完整数据包。
IP 协议
地址结构
IP 地址 = 网络号 + 主机号,通过子网掩码区分。
| 类别 | 地址范围 | 默认子网掩码 |
|---|---|---|
| A 类 | 1.0.0.0 – 126.255.255.255 | 255.0.0.0 /8 |
| B 类 | 128.0.0.0 – 191.255.255.255 | 255.255.0.0 /16 |
| C 类 | 192.0.0.0 – 223.255.255.255 | 255.255.255.0 /24 |
CIDR 无类域间路由
格式:192.168.1.0/24,斜线后数字表示网络位长度。
192.168.1.0/24
网络地址:192.168.1.0
广播地址:192.168.1.255
可用主机:192.168.1.1 – 192.168.1.254(共 254 个)
路由转发
- 数据包头部有目标 IP 地址(始终是最终目的地),不随路由跳转改变
- 每跳通过 ARP 协议获取下一跳的 MAC 地址,填入帧头
- TTL(Time To Live)每经过一个路由器减 1,为 0 时丢弃,防止包无限循环
TCP 三次握手
TCP 三次握手的目标:双方确认各自的发送和接收能力均正常,并协商初始序列号(ISN)。
sequenceDiagram
participant C as 客户端
participant S as 服务端
Note over C: CLOSED
Note over S: LISTEN
C->>S: SYN (seq=x)<br/>客户端发起连接
Note over C: SYN-SENT
S->>C: SYN+ACK (seq=y, ack=x+1)<br/>服务端确认并发起连接
Note over S: SYN-RCVD
C->>S: ACK (ack=y+1)<br/>客户端确认
Note over C: ESTABLISHED
Note over S: ESTABLISHED
为什么是三次而不是两次?
两次握手无法让服务端确认"服务端发出的 SYN-ACK 已被客户端收到",即服务端无法确认自己的发送能力和客户端的接收能力。三次握手后双方都完成了"一发一收"的验证。
为什么不是四次?
四次可以,但没有必要。三次已经足以让双方各完成一次"有去有回"的验证,且 TCP 连接建立后客户端会马上发数据,进一步确认连接状态。
TCP 四次挥手
四次挥手原因:TCP 是全双工的,双方各自独立关闭自己方向的连接,所以需要各发一个 FIN。
sequenceDiagram
participant A as 主动关闭方
participant B as 被动关闭方
A->>B: FIN (seq=u)<br/>我不再发数据了
Note over A: FIN_WAIT_1
B->>A: ACK (ack=u+1)<br/>收到,但我还有数据要发
Note over A: FIN_WAIT_2
Note over B: CLOSE_WAIT
B->>A: FIN (seq=v)<br/>我也不发了
Note over B: LAST_ACK
A->>B: ACK (ack=v+1)<br/>收到
Note over A: TIME_WAIT → 2MSL → CLOSED
Note over B: CLOSED
TIME_WAIT 存在的两个原因:
-
保证最后一个 ACK 能到达 B:若 ACK 丢失,B 会重发 FIN,A 在 TIME_WAIT 期间可以重新发 ACK。若 A 直接关闭,B 的重发 FIN 将得不到响应,B 无法正常关闭。
-
防止旧连接的数据包污染新连接:A 的端口复用后,旧连接在网络中游荡的数据包可能被新连接误收。等待 2MSL(Maximum Segment Lifetime,报文最大生存时间,通常为 30s~2min)可确保旧包全部消亡。
TCP 可靠性机制
序号与确认(累计确认)
每个 TCP 包都有序号(Sequence Number),接收方返回确认号(ACK),表示"该序号之前的数据都已收到,期待下一个包"。这种方式叫累计确认(Cumulative Acknowledgment)。
超时重传与快速重传
| 重传方式 | 触发条件 | 特点 |
|---|---|---|
| 超时重传 | 定时器超期未收到 ACK | 超时间隔自适应(RTT 加权平均),每次超时间隔翻倍 |
| 快速重传 | 收到 3 个重复 ACK | 不等超时,立即重传丢失包,说明网络状况不算太差 |
| SACK | TCP 头扩展字段 | 接收方告知已收到的非连续数据,发送方精准补发 |
滑动窗口
发送方维护一个发送缓冲区,分为 4 个区域:
|--- 已发已确认 ---|--- 已发未确认 ---|--- 未发可发 ---|--- 未发暂不发 ---|
↑ LastByteAcked ↑ LastByteSent ↑ LastByteAcked+AdvertisedWindow
窗口随 ACK 到来向右滑动,允许批量发送多个包而无需等待每个 ACK。
流量控制
接收方在 ACK 中携带接收窗口大小(rwnd),告知发送方自己当前的处理能力。发送方不能发超出窗口的数据。
- 若接收方处理慢,窗口逐渐缩小直至 0,发送方暂停发送
- 发送方定时发窗口探测包,等待接收方恢复窗口
- 防止"糊涂窗口综合征":窗口太小时不立即通告,等到一定阈值再更新
拥塞控制
拥塞窗口(cwnd)控制发送速率,防止把网络塞满。实际发送量 = min(cwnd, rwnd)。
| 阶段 | 行为 | 触发条件 |
|---|---|---|
| 慢启动 | cwnd 指数增长(每 RTT 翻倍) | 连接初始,cwnd=1 |
| 拥塞避免 | cwnd 线性增长(每 RTT +1) | cwnd 超过 ssthresh |
| 快速恢复 | cwnd = ssthresh + 3,线性增长 | 收到 3 个重复 ACK |
| 超时重传 | cwnd=1,重新慢启动,ssthresh=cwnd/2 | 超时 |
TCP BBR 算法:传统拥塞控制以"丢包"作为拥塞信号,BBR 通过测量带宽和 RTT 来估算最优发送速率,在填满管道的同时不填满缓冲区,实现高带宽低时延。
UDP 特性与适用场景
UDP 头部仅 8 字节(源端口、目标端口、长度、校验和),天然"性善",不做任何可靠性保证。
| 特性 | 说明 |
|---|---|
| 无连接 | 不需要建立连接,直接发送 |
| 不可靠 | 不保证送达、不保证顺序、不重传 |
| 无流量控制 | 发多快就多快,不管接收方 |
| 低开销 | 头部小,无握手,延迟低 |
| 支持广播/多播 | TCP 不支持 |
适用场景:
- 实时音视频(WebRTC、直播):丢帧可接受,延迟不可接受
- DNS 查询:单次小包,应用层自己重试
- 游戏:对延迟极敏感,可在应用层实现可靠性
- QUIC(HTTP/3):基于 UDP,在应用层实现可靠传输
TCP vs UDP 选型
| 维度 | TCP | UDP |
|---|---|---|
| 可靠性 | 保证,有重传 | 不保证 |
| 顺序性 | 保证 | 不保证 |
| 连接 | 有连接(三次握手) | 无连接 |
| 延迟 | 较高(握手+重传) | 低 |
| 吞吐量 | 受拥塞控制限制 | 无限制 |
| 广播/多播 | 不支持 | 支持 |
| 适用 | 文件传输、HTTP、数据库 | 音视频、DNS、游戏 |
选型原则:对数据完整性要求高、顺序敏感 → TCP;对延迟敏感、允许少量丢失、需要自定义可靠性策略 → UDP。
参考资料
- 《趣谈网络协议》— 刘超,极客时间,第 2、10、11、12 讲
- RFC 793 (TCP)、RFC 768 (UDP)、RFC 791 (IP)
评论 (0)
发表评论