# TCP 传输控制协议

2024年1月11日17分钟阅读

- FormalSciences/ComputerScience
- ComputerNetwork/Protocols

## 概述

TCP（传输控制协议）始于 1970 年代，由 Vint Cerf 和 Bob Kahn 两位 DARPA（美国国防高级研究计划局）的科学家共同开发。TCP 作为互联网协议套件的核心部分，最初是为了在网络节点之间分享资源而设计的，采用了分组交换技术。

最初的 TCP 协议在 1974 年由 Vint Cerf、Yogen Dalal 和 Carl Sunshine 提出，并于 1974 年底公布了 RFC 675 文件，这是 TCP 的首次正式规范。TCP 最早是作为一个统一的传输控制程序出现的，后来被分解为模块化的架构，形成了 TCP 和 IP 两个独立的协议。这一过程最终演变成了非正式称呼的 TCP/IP 模型。

TCP/IP 在 1983 年被采纳为 ARPANET（互联网的前身）的协议标准，标志着 TCP/IP 正式成为互联网的基础。2004 年，Vint Cerf 和 Bob Kahn 因其在 TCP/IP 上的基础性工作而获得了图灵奖。

TCP 作为一种面向连接的协议，其建立连接的过程采用了三次握手机制，确保了连接的可靠性。 它还实现了重传和错误检测机制，提高了数据传输的可靠性。与此同时，TCP 也提供了网络拥塞避免的机制。TCP 头部通常包含 20 字节大小，用于连接和数据传输的控制信息，后面可以跟随最多 40 字节的额外信息。

随着互联网的发展，TCP 经历了多次更新和改进，以适应不断变化的网络环境和需求。总的来说，TCP 作为互联网的关键部分，对计算机网络的发展历史产生了深远的影响

TCP（传输控制协议）是一种面向连接的、可靠的、基于字节流的传输层通信协议，广泛用于互联网上的数据传输。以下是对 TCP 协议的系统全面讲解：

## TCP 核心特性

- 面向连接： TCP 是一种面向连接的协议，意味着在数据开始传输之前，必须先在发送方和接收方之间建立一个稳定的连接。
- 可靠性： TCP 提供可靠的数据传输服务。这是通过序列号、确认应答、数据重传以及校验和机制来实现的。如果数据在传输过程中丢失或出错，TCP 将重新发送这些数据。
- 流量控制： TCP 使用滑动窗口机制进行流量控制，以防止网络拥堵。这确保了发送方不会超过接收方处理能力的速度发送数据。
- 拥塞控制： TCP 实现了拥塞控制算法（如慢启动、拥塞避免、快速恢复和快速重传），以应对网络中的拥塞情况。这些机制有助于动态调整数据传输速率，以避免网络过载。
- 三次握手机制： TCP 连接的建立采用三次握手机制（SYN，SYN-ACK，ACK），确保双方都准备好进行数据传输。
- 四次挥手断开连接： TCP 连接的终止是通过四次挥手过程来实现的，确保双方都已完成数据传输并同意关闭连接。
- 有序传输： TCP 保证数据按照发送的顺序到达接收端。如果接收到的数据片段不是按顺序的，TCP 将重新排序，以确保数据的正确顺序。
- 端到端通信： TCP 提供端到端的通信。每个 TCP 连接唯一地被定义为包含源 IP 地址、源端口、目的 IP 地址和目的端口的四元组。

## TCP 连接建立和终止

    sequenceDiagram
        participant 客户端
        participant 服务器

        Note over 客户端,服务器: TCP连接建立（三次握手）
        客户端->>服务器: SYN (初始化连接)
        Note right of 服务器: 服务器接收SYN
        服务器->>客户端: SYN-ACK (确认SYN)
        Note left of 客户端: 客户端接收SYN-ACK
        客户端->>服务器: ACK (完成连接建立)
        Note right of 服务器: 连接建立成功

        Note over 客户端,服务器: 数据传输
        Note left of 客户端: 客户端发送数据
        Note right of 服务器: 服务器接收并处理数据
        Note right of 服务器: 服务器发送数据
        Note left of 客户端: 客户端接收并处理数据

        Note over 客户端,服务器: TCP连接终止（四次挥手）
        客户端->>服务器: FIN (请求关闭连接)
        Note right of 服务器: 服务器接收FIN
        服务器->>客户端: ACK (确认FIN)
        Note left of 客户端: 客户端接收ACK
        Note right of 服务器: 服务器准备关闭
        服务器->>客户端: FIN (请求关闭连接)
        Note left of 客户端: 客户端接收FIN
        客户端->>服务器: ACK (确认并关闭连接)
        Note right of 服务器: 连接关闭成功

### TCP 连接建立（三次握手）

1. SYN（同步）：
   1. 客户端发送一个 SYN（同步）数据包到服务器，并在数据包中指定客户端的初始序列号（ISN）。这个序列号是随机生成的，用于标识传输的数据段。
   2. 这表示客户端希望建立连接，并开始序列号计数。
2. SYN-ACK（同步确认）：
   1. 服务器接收到 SYN 数据包后，回复一个 SYN-ACK 数据包。这个数据包同时承载着服务器的初始序列号，以及对客户端 SYN 的确认。
   2. 服务器的确认号是客户端序列号加一，表示服务器已经准备好接收客户端从该序列号开始的数据。
3. ACK（确认）：
   1. 客户端收到 SYN-ACK 后，发送一个 ACK 数据包给服务器。这个 ACK 数据包包含客户端对服务器 SYN-ACK 的确认。
   2. 客户端的确认号是服务器序列号加一，表示客户端已准备好接收服务器从该序列号开始的数据。
   3. 此时，连接建立完成，双方可以开始数据传输。

### TCP 连接终止（四次挥手）

1. FIN（结束）：
   1. 当客户端完成数据发送后，它发送一个带有 FIN 标志的数据包给服务器，表明客户端已经没有数据要发送了，并希望关闭连接。
2. ACK（确认）：
   1. 服务器收到 FIN 后，发送一个 ACK 数据包给客户端，确认已经收到客户端的结束请求。
   2. 服务器此时可能还有数据需要发送给客户端。
3. 服务器的 FIN：
   1. 一旦服务器也完成了数据发送，它同样发送一个带有 FIN 标志的数据包给客户端，表示希望终止连接。
4. 客户端的 ACK：
   1. 客户端接收服务器的 FIN 后，发送 ACK 来确认收到服务器的结束请求。
   2. 在发送最后一个 ACK 后，客户端会进入 TIME_WAIT 状态，持续一段时间以确保服务器收到了 ACK，防止网络延迟造成的数据包丢失。

## TCP 头部结构

字段名称 | 大小（位） | 描述
--- | --- | ---
源端口 | 16 | 标识发送方的端口号。
目的端口 | 16 | 标识接收方的端口号。
序列号 | 32 | 数据段的序列号，用于保证数据的顺序传输。
确认号 | 32 | 确认接收到的数据，通常是期望收到的下一个数据段的序列号。
数据偏移 | 4 | 指示 TCP 头部的长度，以便确定数据内容的起始位置。
保留 | 6 | 为将来使用保留的位，目前必须设置为 0。
标志位 | 6 | 包含多个控制标志，如 SYN、ACK、FIN 等，用于控制 TCP 的状态。
窗口大小 | 16 | 控制发送方的数据量，用于流量控制。
校验和 | 16 | 用于错误检测的校验和。
紧急指针 | 16 | 当 URG 标志位为 1 时，标识紧急数据的结束位置。
选项（可选） | 可变 | 可选字段，用于不同的扩展功能，如最大报文段长度（MSS）、窗口扩大因子等。
填充 | 可变 | 确保 TCP 头部长度是 32 位字的整数倍，仅在必要时添加。

标志位 | 名称 | 描述
--- | --- | ---
URG | 紧急指针 | 当设置为 1 时，表示紧急指针字段有效。通常用于传输紧急数据。
ACK | 确认应答 | 当设置为 1 时，表示确认号字段有效。几乎所有的 TCP 包除了最初的 SYN 包都会设置这个标志。
PSH | 推送函数 | 当设置为 1 时，建议接收方应尽快将这个报文段交给应用层，而不是等缓冲区满了再发送。
RST | 复位 | 当设置为 1 时，表示连接中出现严重错误（如因主机崩溃或其他原因），必须释放连接，然后重新建立传输。
SYN | 同步序列号 | 在连接建立时用来同步序列号。当一个端点希望建立连接时，SYN 标志被设置为 1。
FIN | 结束 | 当设置为 1 时，表示发送端没有数据再发送，即希望结束连接。

## 数据传输

- 序列号和确认号：序列号用于标识从 TCP 源端向目的端发送的数据字节流的每一个字节，确保数据的有序传递。确认号用于确认收到的数据，并且请求下一个预期的序列号，从而实现对丢失数据的重传。
- 数据分段和重组：TCP 将较大的数据块分割成更小的段进行传输，这样做可以提高网络的效率和可靠性。接收端负责将这些小段按照序列号重新组装成原始数据。
- 可靠传输机制：TCP 通过使用校验和、序列号、确认应答以及超时重传等机制，确保数据完整性和可靠性。

## 流量控制

- 滑动窗口机制：滑动窗口是一种流量控制技术，它允许发送方根据接收方的处理能力和缓冲区大小调整其发送速率，从而避免接收方被过量数据淹没。
- 窗口更新：TCP 通过不断调整窗口大小（即可发送或接收的数据量）来适应网络条件和接收端的处理能力。
- 阻塞控制：在接收端缓冲区满时，它会通过设置窗口大小为零来通知发送端停止发送数据，直到缓冲区有足够的空间再次接收数据。

## 拥塞控制

- 慢启动和拥塞避免：TCP 通过慢启动算法开始传输过程，逐渐增加拥塞窗口的大小来探测网络容量。当达到一个阈值后，便转换到拥塞避免阶段，这时窗口的增长会变得更加保守。
- 快速重传和快速恢复：在发生丢包时，TCP 通过快速重传机制重新发送丢失的包，而不是等待超时重传计时器的到期。快速恢复算法则是在检测到丢包后调整拥塞窗口和阈值，以快速恢复正常的传输速率。
- 拥塞窗口：拥塞窗口大小是根据网络的拥塞程度动态调整的，以控制在任一时刻发送到网络上的数据量，从而减少整体网络的拥塞。

## TCP 与 UDP 的比较

特性/协议 | TCP | UDP
--- | --- | ---
类型 | 面向连接的协议 | 无连接的协议
可靠性 | 可靠（保证数据正确传输） | 不可靠（无法保证数据的正确传输）
连接建立 | 需要三次握手建立连接 | 无需建立连接，直接发送数据
速度/效率 | 相对较慢，因为要求确认和错误恢复 | 较快，适用于对实时性要求高的应用
数据传输方式 | 字节流 | 数据报
顺序传递保证 | 是（保证数据按顺序到达） | 否
拥塞控制 | 有（如慢启动、拥塞避免） | 无
流量控制 | 有（使用滑动窗口机制） | 无
头部开销 | 较大（20 字节最小） | 较小（8 字节最小）
用途示例 | 网页浏览、文件传输、电子邮件等 | 实时视频会议、在线游戏、语音通话等
错误检测和修正 | 有（通过序列号和确认应答） | 有错误检测，但无修正（只有校验和）
数据包排序 | 自动重新排序乱序到达的数据包 | 不对数据包进行排序
实时性 | 适用于对可靠性要求高的场景 | 适用于对实时性要求高的场景

## 应用场景

TCP 广泛应用于需要可靠数据传输的场景，如 Web 浏览（HTTP/HTTPS）、文件传输（FTP）、电子邮件（SMTP、IMAP、POP3）等。

TCP 协议的设计使其成为互联网中最可靠的数据传输协议之一，适用于大多数需要高可靠性的网络应用。虽然在某些方面（如实时性和传输效率）可能不如 UDP，但其稳定和可靠的特性使其在网络通信中占有极其重要的地位。