外观
TCP 怎么保证可靠性的
⭐ 题目日期:
字节 - 2024/09/03
📝 题解:
TCP 通过一系列机制确保数据传输的 可靠性,包括 有序性、完整性、去重性 和 容错性。以下是其实现可靠传输的核心机制:
1. 序列号与确认应答(Sequence & Acknowledgment)
- 序列号(Sequence Number)每个数据包携带唯一序列号,标识数据顺序。例如:
- 发送方发送
Seq=1, len=100
→ 接收方预期下一序列号为101
。
- 发送方发送
- 确认应答(ACK) 接收方返回 ACK=下一期望序列号,确认已正确接收数据。 示例:
- 发送
Seq=1, len=100
→ 接收方返回ACK=101
。
- 发送
- 累积确认:ACK 表示之前所有数据已接收,例如
ACK=101
确认了序列号 1~100 的数据。
2. 超时重传(Retransmission)
- 重传计时器(RTO, Retransmission Timeout) 发送方为每个未确认的数据包启动计时器,若超时未收到 ACK,重传该数据包。
- 动态 RTO 计算:基于 RTT(Round Trip Time)动态调整超时阈值,适应网络波动。
- 示例场景:
- 发送方发送
Seq=1
,RTO 设为 200ms。 - 200ms 后未收到
ACK=101
→ 重传Seq=1
。
- 发送方发送
3. 快速重传(Fast Retransmit)
- 重复 ACK 触发:当发送方连续收到 3 个相同的 ACK,认为数据包丢失,立即重传。
- 示例: 发送方发送
Seq=1, 2, 3, 4
→ 接收方收到1, 2, 4
→ 连续返回ACK=3
。 发送方收到 3 次ACK=3
→ 立即重传Seq=3
,无需等待超时。
- 示例: 发送方发送
4. 滑动窗口(Sliding Window)
- 流量控制:接收方通过 窗口大小(Window Size) 告知发送方可接收的数据量。
- 动态调整:窗口大小随接收方缓冲区剩余空间变化,防止发送方过载接收方。
- 发送窗口机制:
- 发送方仅发送窗口内的数据。
- 窗口滑动条件:收到旧数据的 ACK 后,窗口向前滑动,允许发送新数据。
5. 数据校验和(Checksum)
- 完整性验证:发送方计算数据包的校验和,接收方验证校验和。
- 若校验和错误,接收方直接丢弃数据包,不返回 ACK → 触发发送方重传。
6. 连接管理(三次握手与四次挥手)
- 三次握手建立连接:确保双方序列号****同步且通信能力正常。
- 示例:
客户端 → SYN(Seq=x) → 服务端 服务端 → SYN-ACK(Seq=y, ACK=x+1) → 客户端 客户端 → ACK(ACK=y+1) → 服务端
- 四次挥手释放连接:确保双方数据传输完成且无残留数据。
- 示例:
主动方 → FIN(Seq=x) → 被动方 被动方 → ACK(ACK=x+1) → 主动方 被动方 → FIN(Seq=y) → 主动方 主动方 → ACK(ACK=y+1) → 被动方
7. 拥塞控制(Congestion Control)
- 慢启动(Slow Start):初始阶段指数级增大窗口,快速探测可用带宽。
- 拥塞避免(Congestion Avoidance):接近拥塞阈值时,线性增长窗口。
- 拥塞发生时的响应:
- 超时丢包:窗口重置为 1,重新慢启动。
- 快速重传:窗口减半,进入快速恢复阶段。
- 现代算法:如 CUBIC(基于三次函数的窗口增长)和 BBR(基于带宽和延迟测量)。
8. 去重与有序性
- 序列号排序:接收方根据序列号对数据包排序,丢弃重复包。
- 按序交付:仅将连续有序的数据提交给应用层,乱序数据暂存缓冲区。
可靠性保障流程示例
- 发送数据:发送方将数据分段,添加序列号,放入发送窗口。
- 接收确认:接收方校验数据,返回 ACK 或重复 ACK。
- 处理丢包:
- 若超时未收到 ACK → 超时重传。
- 若收到 3 个重复 ACK → 快速重传。
- 滑动窗口:根据 ACK 和窗口大小,动态调整发送速率。
- 拥塞控制:通过算法限制发送速率,避免网络过载。
总结
TCP 的可靠性通过以下机制协同实现:
- 确认与重传:确保数据到达(ACK)或补发丢失数据(超时/快速重传)。
- 序列号与排序:保证数据有序性和去重。
- 校验和:验证数据完整性。
- 流量与拥塞控制:防止发送速率超过接收方或网络的处理能力。
- 连接管理:确保通信双方状态同步。
这些机制使 TCP 能在不可靠的 IP 层之上,提供稳定、有序、无差错的数据传输服务。