模块介绍
TCP(传输控制协议,Transmission Control Protocol)是 TCP/IP 协议族中最核心的传输层协议,也是互联网稳定运行的基石。它是一种面向连接、可靠的、全双工、面向字节流的通信协议,专为对数据可靠性要求高的场景设计,如网页浏览、文件传输、邮件发送等。
本模块将从 TCP 的报文结构、连接管理、可靠传输、流量控制到拥塞控制,带你彻底拆解 TCP 的底层工作机制,同时覆盖高频考点与常见问题,帮你吃透 TCP 的核心原理。
一、TCP 协议核心特性
TCP 的所有设计都围绕「可靠传输」展开,它的核心特性可以概括为以下 5 点:
表格
| 特性 | 详细说明 | 核心价值 |
|---|---|---|
| 面向连接 | 通信双方在传输数据前,必须通过「三次握手」建立逻辑连接;传输完成后,通过「四次挥手」释放连接。 | 为后续可靠传输建立状态基础,避免无连接通信的不可控问题。 |
| 可靠传输 | 通过确认应答、超时重传、序号机制,保证数据不丢失、不重复、按顺序到达。 | 解决网络层 IP 数据报的不可靠问题,为上层应用提供可靠的传输服务。 |
| 全双工通信 | 通信双方可以同时发送和接收数据,连接的两端各有独立的发送缓冲区和接收缓冲区。 | 支持双向数据交互,适配网页、聊天等需要双向通信的场景。 |
| 面向字节流 | TCP 将应用层数据视为连续的字节流,无固定报文边界,数据会被拆分成分段传输,接收方再重组。 | 适配不同链路的最大传输单元,同时简化上层应用的传输逻辑。 |
| 拥塞与流量控制 | 内置拥塞控制和流量控制机制,根据网络状态和接收方能力动态调整发送速率。 | 避免网络拥塞和接收方缓冲区溢出,保障通信稳定性。 |
二、TCP 报文段结构深度解析
TCP 报文段(Segment)是 TCP 协议的数据单元,由「TCP 头部」和「数据载荷」两部分组成,头部结构是理解 TCP 工作机制的关键。
1. TCP 头部固定字段(20 字节)
表格
| 字段 | 长度 | 作用详解 |
|---|---|---|
| 源端口号 | 16 位 | 标识发送方进程的端口,与 IP 地址结合形成源套接字。 |
| 目的端口号 | 16 位 | 标识接收方进程的端口,与 IP 地址结合形成目的套接字。 |
| 序号(Sequence Number, SN) | 32 位 | 本报文段所携带数据的第一个字节的序号。在连接建立时,双方会交换初始序号(ISN),后续数据按序号依次递增,用于数据的按序重组和去重。 |
| 确认号(Acknowledgment Number, ACK) | 32 位 | 期望收到对方下一个报文段的序号,值为「已成功收到的最后一个字节的序号 + 1」。只有 ACK 标志位为 1 时,确认号才有效。 |
| 数据偏移 | 4 位 | 表示 TCP 头部的长度,单位为 4 字节。TCP 头部最小长度为 20 字节(数据偏移 = 5),最大长度为 60 字节(数据偏移 = 15,包含 40 字节选项)。 |
| 保留位 | 6 位 | 预留字段,固定为 0,暂未使用。 |
| 标志位(控制位) | 6 位 | 包含 6 个关键标志位,用于控制连接状态,是三次握手、四次挥手的核心:• URG:紧急指针有效• ACK:确认号有效• PSH:推送操作,接收方应立即将数据交给应用层• RST:重置连接,强制中断通信• SYN:同步序号,用于连接建立• FIN:释放连接,标识数据发送完成 |
| 窗口大小 | 16 位 | 发送本报文段的一方的接收窗口大小,用于实现流量控制,告知对方自己的接收缓冲区剩余空间。 |
| 校验和 | 16 位 | 对 TCP 头部、数据载荷和伪头部进行校验,检测数据在传输中是否损坏。 |
| 紧急指针 | 16 位 | 仅当 URG 标志位为 1 时有效,指向紧急数据的最后一个字节的序号,用于传输紧急数据。 |
2. TCP 头部选项字段(最多 40 字节)
选项字段是 TCP 头部的扩展部分,用于实现增强功能,常见选项包括:
- 最大分段大小(MSS):双方协商的 TCP 报文段数据部分的最大长度,通常等于链路 MTU 减去 IP 头部和 TCP 头部的长度(如以太网 MTU=1500 字节,MSS=1460 字节)。
- 窗口扩大选项:将窗口大小的有效位数从 16 位扩展到 32 位,支持更大的滑动窗口,提升传输效率。
- 时间戳选项:用于计算往返时间(RTT),优化超时重传时间(RTO)的计算,同时防止序号绕回。
- 选择确认(SACK)选项:允许接收方确认收到的非连续数据块,发送方仅重传丢失的部分,提升丢包恢复效率。
三、TCP 连接管理:三次握手与四次挥手
TCP 是面向连接的协议,连接的建立和释放都有严格的流程,也是网工 / 开发面试的高频考点。
1. TCP 连接建立:三次握手
三次握手的核心目的是同步双方的初始序号(ISN),并确认双方的发送和接收能力正常,建立可靠的通信状态。
完整流程拆解
表格
| 阶段 | 发送方→接收方 | 报文段关键信息 | 双方状态变化 | 核心作用 |
|---|---|---|---|---|
| 第一次握手 | 客户端→服务器 | SYN=1,序号 =ISN(c),不携带数据 | 客户端:CLOSED → SYN_SENT | 客户端向服务器发送连接请求,同步自己的初始序号。 |
| 第二次握手 | 服务器→客户端 | SYN=1, ACK=1,序号 =ISN(s),确认号 =ISN(c)+1,不携带数据 | 服务器:LISTEN → SYN_RCVD | 服务器确认收到客户端的连接请求,同时同步自己的初始序号。 |
| 第三次握手 | 客户端→服务器 | ACK=1,序号 =ISN(c)+1,确认号 =ISN(s)+1,可携带数据 | 客户端:SYN_SENT → ESTABLISHED服务器收到后:SYN_RCVD → ESTABLISHED | 客户端确认收到服务器的同步请求,连接正式建立。 |
关键考点:为什么是三次握手?两次握手为什么不行?
- 若只有两次握手,服务器无法确认客户端是否收到了自己的 SYN 报文,会导致服务器维护大量半连接状态,浪费资源(也是 SYN 洪水攻击的原理)。
- 三次握手可以同步双方的序号,避免历史连接的旧报文被误认为新连接,保证通信的正确性。
2. TCP 连接释放:四次挥手
TCP 是全双工通信,双方都可以独立关闭发送方向,因此连接释放需要四次交互,核心目的是确认双方的数据都已发送完成,并释放连接资源。
完整流程拆解
表格
| 阶段 | 发送方→接收方 | 报文段关键信息 | 双方状态变化 | 核心作用 |
|---|---|---|---|---|
| 第一次挥手 | 主动关闭方→被动关闭方 | FIN=1,序号 =u | 主动关闭方:ESTABLISHED → FIN_WAIT_1 | 主动关闭方告知被动方:自己的数据已发送完成,不再发送数据。 |
| 第二次挥手 | 被动关闭方→主动关闭方 | ACK=1,序号 =v,确认号 =u+1 | 被动关闭方:ESTABLISHED → CLOSE_WAIT主动关闭方收到后:FIN_WAIT_1 → FIN_WAIT_2 | 被动关闭方确认收到 FIN 报文,此时主动方的发送方向已关闭,但被动方仍可发送数据(半关闭状态)。 |
| 第三次挥手 | 被动关闭方→主动关闭方 | FIN=1,序号 =w,确认号 =u+1 | 被动关闭方:CLOSE_WAIT → LAST_ACK | 被动关闭方告知主动方:自己的数据也已发送完成,准备关闭连接。 |
| 第四次挥手 | 主动关闭方→被动关闭方 | ACK=1,序号 =u+1,确认号 =w+1 | 主动关闭方:FIN_WAIT_2 → TIME_WAIT(持续 2MSL)被动关闭方收到后:LAST_ACK → CLOSED | 主动关闭方确认收到 FIN 报文,被动方连接释放完成;主动方等待 2MSL 后,连接彻底释放。 |
关键考点:为什么 TIME_WAIT 状态需要持续 2MSL?
- MSL(最大报文段生存时间):TCP 报文段在网络中的最大存活时间,通常为 2 分钟。
- 等待 2MSL 的目的:
- 确保被动关闭方收到第四次挥手的 ACK 报文,若 ACK 丢失,被动方会重传 FIN 报文,主动方可以再次回复 ACK。
- 让本连接的所有报文段在网络中消失,避免历史连接的报文被新连接接收,保证通信的正确性。
四、TCP 可靠传输机制
TCP 通过一系列机制,在不可靠的 IP 网络上实现了可靠的数据传输,核心机制包括以下 4 种:
1. 确认应答机制(ACK)
接收方收到数据后,会向发送方回复一个确认报文,告知发送方「已成功收到序号 N 之前的所有数据」。发送方收到确认后,才会认为该部分数据传输完成。
- 累计确认:TCP 默认采用累计确认,一个确认号可以确认所有序号小于该值的数据,减少确认报文的数量,提升传输效率。
2. 超时重传机制
如果发送方发送的数据在指定时间内未收到确认应答,就会认为数据丢失,自动重传该部分数据。
- 超时重传时间(RTO):基于往返时间(RTT)动态计算,RTO = SRTT + 4×RTTVAR,其中 SRTT 是平滑往返时间,RTTVAR 是 RTT 的方差,避免固定超时时间导致的效率问题。
3. 滑动窗口协议
滑动窗口是 TCP 实现高效传输的核心机制,它允许发送方在未收到确认的情况下,连续发送多个报文段,无需等待每个报文的确认,大幅提升传输效率。
- 发送窗口:发送方允许连续发送的未确认数据的序号范围,大小由接收方的接收窗口和网络拥塞状态共同决定。
- 接收窗口:接收方的接收缓冲区剩余空间,通过报文段的「窗口大小」字段告知发送方,用于流量控制。
- 工作流程:发送方每收到一个确认,发送窗口就向后滑动,允许发送新的数据;接收方每处理完一段数据,接收窗口也向后滑动,更新窗口大小。
4. 选择确认(SACK)机制
当接收方收到非连续的数据时,会通过 SACK 选项告知发送方哪些数据块已收到,发送方仅重传丢失的部分,避免不必要的重传,提升丢包恢复效率。
五、TCP 流量控制
流量控制的核心目的是避免发送方发送过快,导致接收方的接收缓冲区溢出,数据丢失。
1. 流量控制的实现原理
TCP 通过接收方的「接收窗口大小」实现流量控制:
- 接收方每次回复确认报文时,会在「窗口大小」字段告知发送方自己的接收缓冲区剩余空间。
- 发送方的发送窗口大小,不能超过接收方的接收窗口大小,避免发送过快。
2. 常见问题与解决机制
- 零窗口通知:当接收方的接收缓冲区已满时,会回复窗口大小为 0 的报文,告知发送方停止发送数据。
- 窗口更新:当接收方处理完部分数据,缓冲区有剩余空间时,会主动发送窗口更新报文,告知发送方可以继续发送数据。
- 糊涂窗口综合症:当接收方每次仅释放少量缓冲区空间,导致发送方只能发送小报文,传输效率低下。TCP 通过以下方式解决:
- 接收方不发送小窗口更新,直到缓冲区空间足够大。
- 发送方不发送小报文,直到数据达到一定大小或收到窗口更新。
六、TCP 拥塞控制
拥塞控制的核心目的是避免过多数据注入网络,导致全网拥塞,所有主机的传输效率下降。它与流量控制的区别在于:流量控制是控制发送方与接收方之间的端到端速率,而拥塞控制是控制发送方注入网络的速率,避免网络过载。
1. 核心控制算法(经典 Reno 算法)
TCP 的拥塞控制由 4 个核心算法组成,围绕「拥塞窗口(cwnd)」动态调整发送速率:
表格
| 算法阶段 | 触发条件 | 核心规则 | 作用 |
|---|---|---|---|
| 慢启动 | 连接刚建立或超时重传后 | 拥塞窗口从 1 个 MSS 开始,每收到一个 ACK,cwnd += 1;每经过一个 RTT,cwnd 翻倍。 | 快速探测网络可用带宽,避免一开始就发送大量数据导致拥塞。 |
| 拥塞避免 | cwnd 达到慢启动阈值(ssthresh)后 | 每经过一个 RTT,cwnd += 1,线性增长。 | 缓慢增加发送速率,避免过快导致网络拥塞。 |
| 快重传 | 发送方收到 3 个重复的 ACK | 无需等待超时,直接重传丢失的报文段。 | 快速检测丢包,降低重传延迟,避免超时重传导致的速率骤降。 |
| 快恢复 | 触发快重传后 | 将 ssthresh 设置为当前 cwnd 的一半,cwnd = ssthresh,进入拥塞避免阶段,而非慢启动。 | 避免丢包后发送速率骤降,保持较高的传输效率。 |
2. 现代拥塞控制算法
- CUBIC:Linux 系统默认的拥塞控制算法,基于三次函数调整拥塞窗口,在高速网络中表现更优,兼顾公平性和带宽利用率。
- BBR:基于带宽和延迟的拥塞控制算法,不依赖丢包判断拥塞,在高带宽、高延迟的网络中表现出色,常用于流媒体、CDN 等场景。
七、TCP 常见问题与高频考点
1. TCP 粘包与拆包问题
- 问题原因:TCP 是面向字节流的协议,无固定报文边界,应用层的多个数据可能被合并为一个报文段发送(粘包),或一个大数据被拆分为多个报文段发送(拆包)。
- 解决办法:
- 固定报文长度,接收方按固定长度读取数据。
- 在报文头部添加长度字段,接收方根据长度读取完整报文。
- 使用特殊分隔符(如换行符)区分报文边界。
2. SYN 洪水攻击
- 原理:攻击者发送大量伪造的 SYN 报文,服务器回复 SYN+ACK 后,攻击者不回复 ACK,导致服务器维护大量半连接状态,占用资源,无法处理正常请求。
- 防御方式:开启 SYN Cookie、缩短半连接超时时间、过滤伪造 IP 的 SYN 报文。
3. TIME_WAIT 优化
- 问题:高并发场景下,大量 TIME_WAIT 状态的连接会占用系统端口和资源,导致新连接无法建立。
- 优化方式:开启 TCP_TIMESTAMPS 和 TCP_TW_RECYCLE(部分系统支持)、调整端口范围、复用 TIME_WAIT 连接。
模块总结与学习指引
TCP 协议的核心是「可靠传输」,所有设计都围绕这一目标展开:
- 通过三次握手建立连接,同步双方序号;通过四次挥手释放连接,保证数据传输完成。
- 通过序号、确认应答、超时重传、滑动窗口实现可靠传输。
- 通过接收窗口实现流量控制,通过拥塞窗口实现拥塞控制,兼顾传输效率与网络稳定性。
TCP 协议是网络通信的基石,也是后续 HTTP/HTTPS、FTP 等应用层协议的底层支撑,建议结合抓包工具(如 Wireshark)实际分析 TCP 报文段,加深对三次握手、四次挥手和可靠传输机制的理解。
No responses yet