深入解析TCP核心机制:连接管理、流量与拥塞控制

目录

一、三次握手与四次挥手:可靠连接的建立与终止

[1. 三次握手 - 建立连接](#1. 三次握手 - 建立连接)

为什么是三次?

[2. 四次挥手 - 终止连接](#2. 四次挥手 - 终止连接)

为什么需要TIME_WAIT状态?

二、流量控制与滑动窗口:解决收发速度不匹配

核心机制:滑动窗口协议

滑动窗口过程:

流程步骤:

三、拥塞控制:解决网络路径拥堵问题

[1. 慢启动](#1. 慢启动)

[2. 拥塞避免](#2. 拥塞避免)

[3. 快重传](#3. 快重传)

[4. 快恢复](#4. 快恢复)


TCP协议是互联网的可靠传输保障,其核心在于如何建立/终止连接、如何确保数据有序无误地送达,以及如何在复杂的网络环境中高效传输。理解这些机制,是掌握网络编程和进行网络故障排查的关键。

一、三次握手与四次挥手:可靠连接的建立与终止

TCP是面向连接的协议,通信前必须建立一条虚拟链路,通信后要有序地释放它。

1. 三次握手 - 建立连接

目的是确认双方的发送和接收能力正常,并同步初始序列号(ISN)。

  • 第一次握手 (SYN=1, seq=x) :客户端发送SYN包(同步位SYN=1)到服务器,并随机生成一个初始序列号(ISN)x。客户端进入 SYN_SENT 状态。

  • 第二次握手 (SYN=1, ACK=1, seq=y, ack=x+1) :服务器收到SYN包,必须确认客户的SYN。同时自己也发送一个SYN包(SYN=1)以及确认号(ACK=1, ack=x+1)。服务器随机生成自己的ISN y。服务器进入 SYN_RCVD 状态。

  • 第三次握手 (ACK=1, ack=y+1) :客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ACK=1, ack=y+1)。此包发送完毕后,客户端和服务器都进入 ESTABLISHED 状态,完成连接建立。

为什么是三次?

主要是为了防止已失效的连接请求报文突然又传到了服务器,从而产生错误。

假设只有两次握手:一个延迟的旧SYN请求到达服务器,服务器会误以为客户端要建立新连接并响应,但客户端实际并无此意,导致服务器空等,浪费资源。三次握手机制下,客户端不会对那个延迟的确认包再进行确认,连接便无法建立。

2. 四次挥手 - 终止连接

TCP连接是全双工的,因此每个方向必须单独地进行关闭。

  • 第一次挥手 (FIN=1, seq=u) :客户端(主动关闭方)发送一个FIN包,用来关闭客户端到服务器的数据传送。客户端进入 FIN_WAIT_1 状态。

  • 第二次挥手 (ACK=1, ack=u+1) :服务器收到FIN后,发回一个ACK包,确认序号为收到的序号加1。服务器进入 CLOSE_WAIT 状态,客户端收到后进入 FIN_WAIT_2 状态。此时,从客户端到服务器的连接已关闭,但服务器到客户端的连接仍然可用

  • 第三次挥手 (FIN=1, seq=v, ack=u+1) :服务器准备好关闭连接时,发送一个FIN包给客户端。服务器进入 LAST_ACK 状态。

  • 第四次挥手 (ACK=1, ack=v+1) :客户端收到FIN后,发回ACK确认,并进入TIME_WAIT 状态。服务器收到ACK后,关闭连接,进入 CLOSED 状态。客户端等待 2MSL(最大报文段生存时间)后,也关闭连接。

为什么需要TIME_WAIT状态?
  1. 可靠地终止连接 :确保客户端最后的ACK能到达服务器。如果ACK丢失,服务器会重发FIN,客户端在TIME_WAIT状态下能再次响应ACK。

  2. 让旧连接的所有报文在网络中消逝:防止之前连接的延迟报文段被之后新建的、相同四元组(源IP、源端口、目的IP、目的端口)的连接错误接收。

二、流量控制与滑动窗口:解决收发速度不匹配

如果发送方发送得太快,接收方的缓冲区可能会被填满,导致数据丢失。流量控制就是解决发送方和接收方速度不匹配的问题

核心机制:滑动窗口协议

  • 接收窗口 (rwnd) :接收方通过TCP首部中的窗口大小 字段,告知发送方自己当前接收缓冲区还有多少可用空间。这个值动态变化。

  • 工作原理

    1. 发送方维护一个发送窗口,其大小不能超过接收方通告的接收窗口大小。

    2. 窗口内的报文段可以连续发送出去,而无需等待确认。

    3. 每当收到一个确认ACK,发送窗口就向前"滑动"。

    4. 接收方处理完数据,腾出新的缓冲区后,会在下一次ACK中更新窗口大小通告给发送方。

举个例子:接收方说:"我的窗口现在大小是3000字节"。发送方就可以连续发送3000字节的数据,而不用每发一个包就停下来等ACK。这极大地提高了信道利用率。

滑动窗口过程:

流程步骤:
  1. 【客户端请求】

    客户端向服务端发送请求数据报文。

  2. 【服务端发送数据 80B】

    服务端收到请求报文后,发送确认报文和 80 字节的数据。

    • 结果:可用窗口 Usable 减少为 120 字节。

    • 发送指针 SND.NXT 向右偏移 80 字节,指向 321(下次发送数据的序列号)。

  3. 【客户端确认 80B】

    客户端收到 80 字节数据后:

    • 接收窗口向右移动 80 字节,接收指针 RCV.NXT 指向 321(期望的下一个报文序列号)。

    • 客户端发送确认报文给服务端。

  4. 【服务端发送数据 120B】

    服务端再次发送 120 字节数据。

    • 结果:可用窗口耗尽,Usable = 0,服务端无法继续发送数据。
  5. 【客户端确认 120B】

    客户端收到 120 字节数据后:

    • 接收窗口向右移动 120 字节,RCV.NXT 指向 441

    • 客户端发送确认报文给服务端。

  6. 【服务端收到 80B 的确认】

    服务端收到对 80 字节数据的确认报文后:

    • 已发送未确认指针 SND.UNA 向右偏移,指向 321

    • 结果:可用窗口 Usable 增大到 80

  7. 【服务端收到 120B 的确认】

    服务端收到对 120 字节数据的确认报文后:

    • 已发送未确认指针 SND.UNA 向右偏移,指向 441

    • 结果:可用窗口 Usable 增大到 200

  8. 【服务端发送数据 160B】

    服务端可以继续发送,于是发送了 160 字节的数据。

    • 结果:发送指针 SND.NXT 指向 601

    • 可用窗口 Usable 减少到 40

  9. 【客户端确认 160B】

    客户端收到 160 字节数据后:

    • 接收窗口向右移动 160 字节,RCV.NXT 指向 601

    • 客户端发送确认报文给服务端。

  10. 【服务端收到 160B 的确认】

    服务端收到对 160 字节数据的确认报文后:

    • 发送窗口向右移动 160 字节,SND.UNA 指针指向 601

    • 结果:可用窗口 Usable 增大至 200

三、拥塞控制:解决网络路径拥堵问题

如果网络本身已经拥堵,此时大量重发数据只会让情况恶化。拥塞控制就是防止过多的数据注入到网络中,避免网络中的路由器或链路过载。它是一个全局性的过程。

TCP的拥塞控制主要基于四个核心算法:

1. 慢启动

  • 连接刚建立时,发送方并不清楚网络状况,需要一种探针机制。

  • 拥塞窗口(cwnd)从1个MSS(最大报文段长度)开始。

  • 每收到一个ACK,cwnd就指数增长(cwnd *= 2)。这就像启动时猛踩油门,速度增长很快。

  • cwnd 达到慢启动门限(ssthresh) 时,进入下一个阶段。

2. 拥塞避免

  • 当窗口变大后,指数增长变得危险。此时进入线性增长阶段。

  • 规则变为:每经过一个往返时延(RTT),cwnd只加1(即每收到一个ACK,cwnd增加 1/cwnd)。

  • 这个过程是在小心翼翼地探测网络的最大可用容量。

3. 快重传

  • 传统超时重传太慢。快重传要求接收方每收到一个失序报文段就立即发出重复确认

  • 如果发送方连续收到3个重复的ACK,就认为该报文段已经丢失,立即重传它,而不必等待超时计时器到期。

4. 快恢复

  • 在快重传之后触发,而非直接进入慢启动。

  • 发送方认为网络状况尚可(因为还能收到3个ACK),只是个别包丢失。

  • ssthresh 设置为当前 cwnd 的一半,并将 cwnd 设置为新的 ssthresh 值(有的实现会加3),然后直接进入拥塞避免阶段。

拥塞控制的整体过程可以概括为:加法增大乘法减小,即在不拥塞时线性增加窗口,在出现拥塞时(超时或收到3个重复ACK)将窗口乘性减半。

相关推荐
七夜zippoe22 分钟前
CANN Runtime任务描述序列化与持久化源码深度解码
大数据·运维·服务器·cann
盟接之桥30 分钟前
盟接之桥说制造:引流品 × 利润品,全球电商平台高效产品组合策略(供讨论)
大数据·linux·服务器·网络·人工智能·制造
会员源码网1 小时前
理财源码开发:单语言深耕还是多语言融合?看完这篇不踩坑
网络·个人开发
米羊1212 小时前
已有安全措施确认(上)
大数据·网络
Fcy6482 小时前
Linux下 进程(一)(冯诺依曼体系、操作系统、进程基本概念与基本操作)
linux·运维·服务器·进程
袁袁袁袁满2 小时前
Linux怎么查看最新下载的文件
linux·运维·服务器
主机哥哥2 小时前
阿里云OpenClaw部署全攻略,五种方案助你快速部署!
服务器·阿里云·负载均衡
ManThink Technology3 小时前
如何使用EBHelper 简化EdgeBus的代码编写?
java·前端·网络
珠海西格电力科技3 小时前
微电网能量平衡理论的实现条件在不同场景下有哪些差异?
运维·服务器·网络·人工智能·云计算·智慧城市
QT.qtqtqtqtqt4 小时前
未授权访问漏洞
网络·安全·web安全