Skip to content

TCP:连接、可靠性、流量控制与拥塞控制 ​

TCP 是 Transmission Control Protocol,中文常叫“传输控制协议”。

如果压缩成一句话,它主要解决的是 在不可靠的网络环境里,如何为应用提供面向连接、可靠、按序的字节流传输。


1. TCP 到底在解决什么问题 ​

网络本身会遇到很多现实问题:

  1. 数据包可能丢
  2. 包可能乱序
  3. 包可能重复
  4. 接收方处理速度可能跟不上
  5. 网络本身可能已经拥塞

TCP 出现,就是为了在这些现实条件下,把传输过程尽量组织得更稳定。

它主要负责:

  1. 建立连接
  2. 可靠传输
  3. 按序交付
  4. 流量控制
  5. 拥塞控制

2. 为什么说 TCP 是“面向连接” ​

面向连接 不是说网线真的被你独占了一根。

更贴近这个概念的说法是:

  1. 双方在正式传数据前,要先建立一段逻辑连接状态
  2. 后续传输过程里,双方都要维护这段连接的状态
  3. 传完后还要有连接释放过程

所以 TCP 的“连接”更像 一段被双方共同维护的通信状态,而不是物理线路。


3. 三次握手在做什么 ​

三次握手不是为了仪式感,而是为了确认两件事:

  1. 我能发给你
  2. 你也能发给我

最简化地理解:

  1. 客户端发 SYN
  2. 服务端回 SYN + ACK
  3. 客户端再回 ACK

这样双方就能确认:

  1. 双向收发能力基本可用
  2. 初始序列号协商完成
  3. 后续可以进入可靠传输阶段

4. 从发起请求到收到响应,TCP 这一层具体在做什么 ​

如果只记“三次握手”,还是不够理解 TCP 在真实请求里扮演的角色。

更完整的过程通常是:

  1. 客户端先和服务端建立连接
  2. 连接建立后,客户端把应用层数据写入发送缓冲区
  3. TCP 把这段字节流切成合适的报文段
  4. 每个报文段带上序列号后发出去
  5. 服务端收到后,会根据序列号确认、重排并交给上层应用
  6. 应用处理后,服务端再把响应数据通过同一连接发回客户端
  7. 客户端继续确认收到的数据,直到本轮请求响应完成
  8. 如果连接不再使用,再进入连接关闭过程

这里最值得记的不是报文格式细节,而是:

TCP 既负责建立连接状态,也负责在连接存在期间持续管理发送、确认、重传、排序和关闭。`


5. 一张 TCP 请求响应过程图 ​

mermaid
sequenceDiagram
    participant Client as 客户端
    participant Server as 服务端

    Client->>Server: SYN
    Server-->>Client: SYN + ACK
    Client->>Server: ACK
    Note over Client,Server: TCP 连接建立

    Client->>Server: 发送请求数据段 seq=100
    Server-->>Client: ACK=...
    Client->>Server: 发送后续数据段
    Server->>Server: 按序重组并交给应用

    Server-->>Client: 返回响应数据段
    Client->>Client: 按序重组并交给应用
    Client-->>Server: ACK=...

    Client->>Server: FIN
    Server-->>Client: ACK
    Server-->>Client: FIN
    Client->>Server: ACK
    Note over Client,Server: TCP 连接关闭

这张图的重点不是让你背每个序列号,而是先理解:

  1. 请求和响应都跑在同一条连接上
  2. 传输过程不是“一发就完”,而是伴随确认和可能的重传
  3. 连接的建立和关闭本身也是协议过程的一部分

6. TCP 为什么能保证可靠和按序 ​

它不是靠“网络突然变可靠”,而是靠自己补机制。

这些机制通常包括:

  1. 序列号
  2. 确认应答 ACK
  3. 超时重传
  4. 乱序重排
  5. 去重

也就是说,TCP 的可靠性来自 协议机制 + 连接状态维护,而不是物理网络天生可靠。


7. 流量控制和拥塞控制不是一回事 ​

这是 TCP 里特别容易混的一组概念。

5.1 流量控制 ​

流量控制更关心:

接收方来不来得及处理。

如果发送方太快,接收方缓冲区可能吃不消。

所以流量控制本质上是端到端双方之间的速度协调。

5.2 拥塞控制 ​

拥塞控制更关心:

整个网络现在是不是已经太堵了。

它不是只看接收方,而是看网络链路整体承受能力。

所以:

  1. 流量控制解决“接收端吃不吃得下”
  2. 拥塞控制解决“网络扛不扛得住”

🌟 这两个词经常一起出现,但解决的问题并不相同。


8. TCP 的能力边界 ​

这部分很重要,因为很多误解都来自把 TCP 想得过大。

6.1 TCP 负责端到端可靠传输 ​

它负责:

  1. 建连接
  2. 维护连接状态
  3. 让字节流尽量可靠、按序送达

6.2 TCP 不负责机器级路由 ​

它依赖下层 IP 去把包送到目标主机。

6.3 TCP 不理解应用语义 ​

对 TCP 来说,网页请求、RPC 调用、聊天消息,本质上都只是字节流。

6.4 TCP 不是“永不丢失” ​

更贴近实际情况的说法是,它会通过重传和控制机制尽量把数据交付给应用,但在超时、异常断连、对端不可达等情况下,连接仍然会失败。


9. 为什么一个 HTTP 请求在 TCP 里看起来像“字节流” ​

这部分非常关键。

对 TCP 来说,它看到的不是:

  1. 这是一个 GET
  2. 这是一个 JSON
  3. 这是一个状态码

它看到的只是连续字节。

例如浏览器发出:

http
GET /api/users/1001 HTTP/1.1
Host: example.com

到了 TCP 这一层,更像是:

  1. 一串待发送字节
  2. 被切分成多个报文段
  3. 再由对端按序重组成原始字节流

所以很多应用层协议都会强调:

  1. 报文边界怎么定义
  2. 长度如何表示
  3. 粘包拆包怎么处理

因为 TCP 提供的是字节流,不替你保留应用层消息边界。


10. 一个最小的连接示意 ​

可以用 curl 观察一个最普通的 TCP 应用场景:

bash
curl -v https://example.com

你会看到请求里有:

  1. 建立连接
  2. 发送请求
  3. 接收响应
  4. 连接复用或关闭

如果进一步抓包,会更容易看到三次握手、数据传输和四次挥手这些过程。


11. 为什么很多业务系统默认偏爱 TCP ​

因为大部分业务系统更关心:

  1. 数据不要乱
  2. 请求不要莫名丢
  3. 结果要可预期

例如:

  1. HTTP/1.1
  2. 数据库连接
  3. RPC
  4. 消息中间件客户端连接

这些场景通常都更偏可靠传输,而不是“少一点协议开销就行”。


12. 常见误区 ​

12.1 以为 TCP 更慢,所以不适合所有高性能场景 ​

不准确。

大量高性能系统依然运行在 TCP 之上,关键要看业务到底要可靠性还是更低时延。

12.2 以为有 TCP 就不需要应用层重试和超时 ​

不是。

TCP 解决的是传输层可靠性,不是业务层成功语义。

12.3 以为三次握手只是背诵题 ​

真正重要的是理解它为什么要确认双向收发能力和连接状态。


13. 一句话总结 ​

TCP 这条主线,本质上是在解决 如何在不可靠网络上,为应用提供面向连接、可靠、按序、可控制速率的字节流传输。

基于 VitePress 构建的个人技术笔记。