TCP(Transmission Control Protocol,传输控制协议)是面向连接的、可靠的、基于字节流的传输层协议。TCP 将应用层数据封装为报文段(Segment)进行传输。
TCP 报文段由首部和数据两部分组成。首部固定部分为 20 字节,可选部分最长 40 字节,因此首部总长 20~60 字节。
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 源端口号 | 目的端口号 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 序号 (Sequence Number) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 确认号 (Acknowledgment Number) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 数据偏移|保留 |C|E|U|A|P|R|S|F| 窗口大小 |
| (4位) |(3位)|W|C|R|C|S|S|Y|I| |
| | |R|E|G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 校验和 | 紧急指针 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 选项(可选,0~40字节) |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 数据 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 字段 | 长度 | 说明 |
|---|---|---|
| 源端口号 | 16 位 | 发送方进程端口号,范围 0~65535 |
| 目的端口号 | 16 位 | 接收方进程端口号 |
| 序号 (Seq) | 32 位 | 本报文段数据的第一个字节在整个字节流中的编号 |
| 确认号 (Ack) | 32 位 | 期望收到对方下一个报文段的第一个字节的编号 |
| 数据偏移 | 4 位 | TCP 首部长度,单位为 4 字节(32 位字),最大值 15,即首部最长 60 字节 |
| 保留 | 3 位 | 保留为将来使用,目前置 0 |
| 标志位 (Flags) | 9 位 | NS, CWR, ECE, URG, ACK, PSH, RST, SYN, FIN(RFC 3168 后为 9 位) |
| 窗口大小 | 16 位 | 接收窗口大小,单位为字节,用于流量控制 |
| 校验和 | 16 位 | 覆盖首部和数据,计算时包括伪首部 |
| 紧急指针 | 16 位 | $URG=1$ 时有效,指出紧急数据的末尾在数据中的偏移 |
| 标志位 | 全称 | 含义 |
|---|---|---|
| NS | Nonce Sum | ECN-nonce 隐藏保护位(RFC 3540),用于防止接收方隐藏丢包 |
| CWR | Congestion Window Reduced | 发送方已按 ECN 要求降低拥塞窗口 |
| ECE | ECN-Echo | ECN 回显。=1 表示对端报告了拥塞(配合 ECN 使用) |
| URG | Urgent | 紧急标志。=1 时紧急指针字段有效,数据需优先处理 |
| ACK | Acknowledgment | 确认标志。=1 时确认号字段有效。连接建立后所有报文段 $ACK=1$ |
| PSH | Push | 推送标志。=1 时接收方应尽快将数据交付应用层,不等缓冲区满 |
| RST | Reset | 复位标志。=1 时表示连接出现严重差错,需释放并重建连接 |
| SYN | Synchronize | 同步标志。=1 时表示连接请求或连接接受(用于三次握手) |
| FIN | Finish | 终止标志。=1 时表示发送方数据已发完,请求释放连接(用于四次挥手) |
常见选项:
TCP 对每个字节编号(不是对报文段编号)。
校验和覆盖范围 = 伪首部 + TCP 首部 + TCP 数据。
伪首部(来自 IP 层,不实际传输):
窗口大小字段(16 位)表示接收窗口大小:
| 概念 | 定义 |
|---|---|
| 报文段 | TCP 传输的数据单元,由首部和数据组成 |
| MSS | 最大报文段长度,TCP 数据部分的最大值(不含首部) |
| 序号 | 数据第一个字节在字节流中的位置 |
| 确认号 | 期望下一个收到的字节编号 |
| 数据偏移 | 首部长度字段,以 4 字节为单位 |
| 累积确认 | 确认号 N 表示 N 之前的所有数据已正确接收 |
| 伪首部 | 用于校验和计算的虚拟首部,来自 IP 层信息 |
| 接收窗口 | 接收方缓冲区还能接收的数据量 |
| MSS vs MTU | $MSS = MTU - IP_{hdr} - TCP_{hdr}$,通常 $MSS = 1460$ 字节 |
题目:某 TCP 报文段的数据偏移字段值为 5(二进制 0101),求首部长度。
题目:某 TCP 报文段数据偏移字段为 15(二进制 1111),且携带了 MSS 选项(4 字节)和窗口扩大因子选项(3 字节)及 1 字节填充。求首部总长度。
题目:A 向 B 发送数据,$MSS = 1000$ 字节。A 已发送了序号为 1001 的报文段(携带 1000 字节数据)。B 的确认号应该是多少?
题目:写出 TCP 三次握手中三个报文段的标志位设置。
| 报文段 | 发送方→接收方 | SYN | ACK | 说明 |
|---|---|---|---|---|
| 第 1 个 | 客户端→服务器 | 1 | 0 | 连接请求,$SYN=1$ |
| 第 2 个 | 服务器→客户端 | 1 | 1 | 同意连接,$SYN=1,ACK=1$ |
| 第 3 个 | 客户端→服务器 | 0 | 1 | 确认,$ACK=1$ |
题目:TCP 校验和计算时为什么要包含伪首部?
| 项目 | 说明 |
|---|---|
| 首部大小 | 固定 20 字节,最大 60 字节 |
| 序号空间 | 32 位,范围 $0 \sim 2^{32}-1$(约 4 GB 后回绕) |
| 窗口大小 | 基本 16 位(最大 65535 字节),可选扩大因子最大 14 位(最大约 1 GB) |
| 端口空间 | 16 位,0~65535(0 保留,1~1023 熟知端口) |
↑ 以上为站内 HTML 相对链接(纯网页可浏览);本页右上「在 Obsidian 中打开」跳回源笔记。