📖 TCP 报文段的首部格式
🎯 课程摘要:本节课详细介绍 TCP 报文段首部各字段的含义与作用,包括序号、确认号、确认标志位 ACK、数据偏移、窗口、检验和、六个标志位(URG/ACK/PSH/RST/SYN/FIN)、紧急指针、选项与填充等,并通过 408 考研真题讲解序号与确认号的计算方法。
📝 详细笔记
1. TCP 报文段首部构成
- TCP 采用面向字节流的方式实现可靠传输,发送时根据发送策略从发送缓存中取出一定数量的字节并添加首部,使之成为 TCP 报文段后发送。
- TCP 的全部功能都体现在首部中各字段的作用,只有弄清各字段才能掌握 TCP 基本工作原理。
- TCP 报文段首部 = 20 字节固定首部 + 最大 40 字节扩展首部(选项),与 IPv4 数据报首部格式类似。
2. TCP 首部各字段总览
| 字段 | 长度 | 作用 |
|---|---|---|
| 源端口 | 16 比特 | 存储源端口号 |
| 目的端口 | 16 比特 | 存储目的端口号 |
| 序号(seq) | 32 比特 | 指出本 TCP 报文段数据载荷的第一个字节的序号 |
| 确认号(ack) | 32 比特 | 指出期望收到对方下一个 TCP 报文段数据载荷的第一个字节的序号,即对之前收到的所有数据的确认 |
| 数据偏移 | 4 比特 | 以 4 字节为单位,指出 TCP 报文段数据载荷起始处距 TCP 报文段起始处多远(即首部长度) |
| 保留 | 6 比特 | 保留供今后使用,目前置为零 |
| 标志位(6 个) | 6 比特 | URG、ACK、PSH、RST、SYN、FIN |
| 窗口 | 16 比特 | 以字节为单位,指出发送本报文段一方的接收窗口大小(接收缓存可用空间) |
| 检验和 | 16 比特 | 检查整个 TCP 报文段在传输过程中是否出现误码 |
| 紧急指针 | 16 比特 | 以字节为单位,指明紧急数据的长度(URG=1 时有效) |
| 选项 | 可变(最大 40 字节) | 增加 TCP 功能(MSS、窗口扩大、时间戳、SACK 等) |
| 填充 | 可变 | 确保首部长度能被 4 字节整除 |
3. 与可靠传输相关的字段
序号字段(seq)
- 占 32 比特,取值范围 0~2^32-1,到末尾后回到零。
- 值用来指出本 TCP 报文段数据载荷的第一个字节的序号。
确认号字段(ack)
- 占 32 比特,取值范围 0~2^32-1,到末尾后回到零。
- 值用来指出期望收到对方下一个 TCP 报文段数据载荷的第一个字节的序号,同时也是对之前收到的所有数据的确认。
- 确认号为 N → 表明到序号 N-1 为止的所有数据都已正确接收,希望接收序号为 N 的数据。
确认标志位 ACK
- 只有当 ACK=1 时,确认号字段才有效;ACK=0 时确认号字段无效。
- ⚠️ 重点/考点:TCP 规定,连接建立后所有传送的 TCP 报文段都必须把 ACK 置 1。
序号与确认号举例
假设 TCP 客户与服务器已通过三报文握手建立连接:
| 报文方向 | seq | 数据载荷 | ack | ACK | 含义 |
|---|---|---|---|---|---|
| 客户 → 服务器 | 201 | 100 字节(序号 201~300) | 800 | 1 | 期望收到序号 800 开始的数据(已收 799 及以前) |
| 服务器 → 客户 | 800 | — | 301 | 1 | 已收 300 及以前,期望收到序号 301 开始的数据 |
4. 408 考研真题演练
真题一(答案 D)
主机甲、乙已建立 TCP 连接。主机甲给主机乙发送第一个 TCP 段:seq=200,数据载荷 300 字节(末字节序号 499)。第二个 TCP 段:seq=500,数据载荷 500 字节(末字节序号 999)。主机乙确认段的 ack = 1000(= 999 + 1)。
真题二(2013 年,答案 B)
主机乙给主机甲发送的 TCP 段 seq=1913,数据载荷 100 字节(末字节序号 2012)。主机乙之前发送的确认号 2046 → 主机甲发送的 TCP 段 seq=2046,ack=2013。
真题三(2011 年,答案 B)
主机甲发送三个连续 TCP 段,主机乙正确接收第一和第三个段(第二个丢失)。主机乙的确认段对已接收且按序到达的最后一个 TCP 段进行确认。第三个段 seq=900,数据载荷 400 字节 → 第二个段首字节序号 500(=900-400),第一个段末字节序号 499 → 确认号 ack=500(= 499 + 1)。
- ⚠️ 重点/考点:确认号是对已接收且按序到达的最后一个字节的序号加一,未按序到达的数据不能累计确认。
5. 数据偏移字段
- 占 4 比特,取值以 4 字节为单位,用来指出 TCP 报文段数据载荷起始处距 TCP 报文段起始处多远,即首部长度。
| 数据偏移值(二进制) | 十进制 | 首部长度 |
|---|---|---|
| 0101 | 5 | 5×4 = 20 字节(最小) |
| 1111 | 15 | 15×4 = 60 字节(最大) |
6. 窗口字段
- 占 16 比特,取值范围 0~2^16-1,以字节为单位。
- 指出发送本报文段一方的接收窗口大小(接收缓存的可用空间),表征接收方的接收能力。
- 用接收方的接收能力控制发送方的数据发送量,即流量控制。
7. 检验和字段
- 占 16 比特,检查整个 TCP 报文段是否出现误码。
- 计算时要在 TCP 报文段前面加上 12 字节的伪首部(与 UDP 类似),其中:
- 左起第三字段保留字节置零
- 第四字段值由 17(UDP)改为 6(TCP,因 IP 协议字段 6 表示 TCP)
- 第五字段由 UDP 长度改为 TCP 长度
发送方计算步骤:
- 将 TCP 首部中检验和字段置零
- 将伪首部、TCP 首部、数据载荷划分成若干 2 字节的字(总长非偶数字节则末尾补全零字节)
- 对全部 2 字节的字进行反码算术运算求和,结果取反码
- 将结果写入 TCP 首部检验和字段
接收方验证步骤:
- 给接收到的 TCP 报文段添加 12 字节伪首部
- 划分成若干 2 字节的字
- 反码算术运算求和并取反码
- 结果为零 → 无误码;非零 → 出现误码
- ⚠️ 重点/考点:IPv4 数据报首部检验和只对首部检验,而 TCP 检验和对整个 TCP 报文段(首部 + 数据载荷)进行检验。
8. 六个标志位
| 标志位 | 全称 | 作用 |
|---|---|---|
| URG(紧急) | Urgent | URG=1 时紧急指针字段有效 |
| ACK(确认) | Acknowledge | ACK=1 时确认号字段有效;连接建立后所有报文段 ACK 必须置 1 |
| PSH(推送) | Push | PSH=1 时发送方立即创建并发送报文段,接收方尽快交付应用进程(用于交互式通信) |
| RST(复位) | Reset | RST=1 表明连接出现严重差错,必须释放连接再重新建立;也可拒绝非法报文段或拒绝打开连接 |
| SYN(同步) | Synchronize | SYN=1 用于三报文握手建立连接;SYN=1 且 ACK=0 为连接请求报文段,SYN=1 且 ACK=1 为连接请求确认报文段 |
| FIN(释放) | Finish | FIN=1 表明发送方数据已全部发送完毕,要求释放 TCP 连接(用于四报文挥手) |
- ⚠️ 重点/考点:SYN=1 的报文段要么是连接请求报文段,要么是连接请求确认报文段。
9. 紧急指针字段与紧急标志位 URG
- URG=1 时紧急指针字段有效,URG=0 时无效。
- 紧急指针占 16 比特,以字节为单位,指明紧急数据的长度。
- 发送方有紧急数据时,可将紧急数据插队到发送缓存最前面,立刻封装到 TCP 报文段发送。
- 紧急指针指出本报文段数据载荷中包含多长的紧急数据,其后是普通数据。
- 接收方收到 URG=1 的报文段后,按紧急指针取出紧急数据直接上交应用进程,不必在接收缓存中排队。
10. 选项与填充
选项字段(最大 40 字节)
| 选项 | 作用 |
|---|---|
| 最大报文段长度 MSS | 指出 TCP 报文段数据载荷的最大长度(非整个报文段长度) |
| 窗口扩大选项 | 扩大窗口,提高吞吐率 |
| 时间戳选项 | 计算往返时间 RTT,还可用于处理序号超范围(防止序号绕回) |
| 选择确认选项(SACK) | 实现选择确认功能 |
填充字段
- 选项字段长度可变,若选项长度 + 20 字节固定首部不能被 4 字节整除,需填充比特零,确保首部长度能被 4 字节整除。
- 原因:数据偏移字段(首部长度)以 4 字节为单位。与 IPv4 数据报首部填充字段用法相同。
💡 核心总结
- TCP 首部 = 20 字节固定 + 最大 40 字节选项,最小 20 字节、最大 60 字节。
- 序号指数据载荷首字节序号;确认号指期望收到的下一个首字节序号(即 N-1 及以前已收)。
- ACK=1 确认号才有效;连接建立后所有报文段 ACK 必须置 1。
- 六个标志位 URG/ACK/PSH/RST/SYN/FIN 各有用途,SYN 用于建连、FIN 用于释放。
- 检验和对整个 TCP 报文段检验(含 12 字节伪首部,协议字段值 6)。
- 数据偏移以 4 字节为单位表示首部长度。
❓ 课后思考 / 经典考题
- TCP 报文段首部最小和最大长度分别是多少?数据偏移字段为何以 4 字节为单位?
- 确认号为 N 表示什么含义?为什么连接建立后所有报文段的 ACK 都必须置 1?
- TCP 检验和与 IPv4 首部检验和的计算范围有何不同?伪首部中协议字段值应设为多少?
- SYN=1 的报文段有哪两种可能?FIN=1 的报文段用于什么场景?
- (408 真题)主机甲发送 seq=200、数据载荷 300 字节的 TCP 段,主机乙正确接收后回复的确认号应是多少?