吃透 TCP 核心原理:从握手挥手到滑动窗口与拥塞控制

一、TCP 报文头部结构与字节分布

TCP 协议传输数据的基本单元是 TCP 报文,每个 TCP 报文由"头部"和"应用层数据"两部分组成。头部是 TCP 协议的核心,包含控制连接、保障可靠传输的所有关键信息,按顺序逐一讲解每个字段(按字节分布从左到右):

TCP 头部固定长度为 20 字节,另有可选字段,长度范围 0~40 字节,因此 TCP 头部总长度范围为 20~60 字节,所有字段按网络字节序排列。

1. 源端口号(16 位,2 字节)

端口号可理解为电脑上各个应用的"门牌号",源端口号是发送该 TCP 报文的应用程序在本机上的端口号。例如浏览器访问网站时,会动态分配一个临时端口作为源端口,用于接收方将应答数据准确送达本机对应的应用程序。

2. 目的端口号(16 位,2 字节)

目的端口号是接收该 TCP 报文的应用程序在对方主机上的端口号。IP 地址用于定位主机,而端口号用于定位主机上的具体应用。例如访问网站时,目的端口号通常为 80(HTTP 协议)或 443(HTTPS 协议),即服务器上 Web 服务的固定端口。

3. 序号(32 位,4 字节)

TCP 是面向字节流的协议,所有传输数据会被拆分为单个字节,每个字节都有唯一编号,即序号。TCP 报文中的序号,特指本报文中所有数据字节的第一个字节编号。

例如,发送 1000 字节数据可拆分为两个报文,第一个报文包含前 500 字节,序号可设为 1;第二个报文包含后 500 字节,序号设为 501。接收方可通过序号将数据按正确顺序拼接,避免乱序。

建立连接时,双方会各自生成随机初始序号并通过报文交换,后续所有数据序号从初始序号开始递增,避免旧连接残留数据干扰新连接。

4. 确认号(32 位,4 字节)

确认号用于告知对方已成功接收的数据范围,表示期望收到的下一个字节序号,即确认号 = 已收到的最后一个字节序号 + 1。

例如,接收方收到序号 1~500 的数据,回复的确认号即为 501,示意对方后续发送从 501 开始的字节。

确认号仅在 ACK 标志位为 1 时有效,除第一次发起连接的纯 SYN 报文外,几乎所有 TCP 报文都会将 ACK 置为 1,确保双方实时确认数据接收情况。

5. 数据偏移 + 保留 + 标志位(共 16 位,2 字节)

该字段由三部分组成,各司其职:

(1)数据偏移(4 位)

用于告知接收方 TCP 头部总长度,因头部可选字段长度不固定,需通过该字段定位应用层数据的起始位置。数据偏移单位为 4 字节,例如值为 5 时,头部总长度 = 5×4 = 20 字节(无可选字段);值为 10 时,头部总长度 = 10×4 = 40 字节(20 字节固定头部 + 20 字节可选字段)。

(2)保留位(6 位)

预留字段,目前无实际作用,按协议规定需全部设为 0,为后续 TCP 功能扩展预留空间。

(3)标志位(6 位)

标志位用于区分报文类型,控制连接建立、断开、数据推送等行为,每一位对应一项功能:

① SYN:同步标志位,用于建立连接,发起连接时置为 1,示意对方同步初始序号;

② ACK:应答标志位,用于确认收到对方数据,置为 1 时确认号字段有效;

③ FIN:结束标志位,用于断开连接,置为 1 示意本方无更多数据发送;

④ PSH:推送标志位,置为 1 时催促对方立即将接收缓冲区数据交给应用层,不继续缓存;

⑤ RST:复位标志位,用于异常时强制断开连接,无需正常断开流程;

⑥ URG:紧急标志位,用于标记报文中包含紧急数据,需配合紧急指针优先处理。

6. 窗口大小(16 位,2 字节)

窗口大小是 TCP 流量控制的核心字段,表示接收方当前可接收的字节数,本质是告知发送方自身接收缓冲区的剩余空间。

接收缓冲区可理解为临时仓库,发送方数据先存入仓库再由应用层读取,若仓库满则后续数据会被丢弃。窗口大小字段让接收方将仓库剩余空间告知发送方,发送方据此调整发送速度,避免缓冲区溢出。

16 位窗口大小最大可表示 65535 字节,无法满足大带宽、高延迟网络需求,可通过可选字段的窗口扩大因子扩展窗口大小。

7. 校验和(16 位,2 字节)

用于检测数据传输过程中的错误,覆盖 TCP 头部、应用层数据及 IP 层伪首部(含源 IP、目的 IP 等)。发送方发送前计算校验和并填入字段,接收方重新计算,若结果不一致则丢弃报文,发送方超时后重传。

8. 紧急指针(16 位,2 字节)

仅在 URG 标志位为 1 时有效,用于指示紧急数据在报文数据部分的位置,让接收方优先处理紧急数据(如取消下载指令),无需按正常顺序排队。

9. 可选字段(0~40 字节)

用于扩展 TCP 功能,弥补固定头部局限性,常见类型包括:

① MSS(最大分段大小):规定单次传输的最大数据段长度(不含头部),由双方建立连接时协商,避免报文过大影响传输效率;

② 窗口扩大因子:将 16 位窗口大小扩展至 30 位,适配大带宽网络;

③ SACK(选择性确认):告知发送方已接收和丢失的报文,避免重传已接收数据;

④ 时间戳:计算数据传输往返时延(RTT),动态调整超时时间,防止序列号重复错误。

10. 报文整体结构总结

TCP 报文结构可简化为:TCP 头部(20~60 字节) + 应用层数据。头部负责控制连接、保障可靠传输,数据部分承载实际应用信息。

二、流量控制

若发送方数据发送速度远超接收方处理速度,接收方缓冲区会快速被填满,后续数据被丢弃,发送方需重传,既浪费资源又降低效率。TCP 流量控制机制通过窗口大小字段解决这一问题。

具体流程:接收方每次回复 ACK 报文时,将当前接收缓冲区剩余空间填入窗口大小字段发送给发送方,发送方根据该值调整发送速度,确保每次发送数据量不超过窗口大小。

例如,接收方缓冲区剩余 2000 字节,窗口大小设为 2000,发送方单次发送不超过 2000 字节;接收方处理 1000 字节后,缓冲区剩余 3000 字节,下次应答时更新窗口大小为 3000,发送方相应提高发送速度。

三、三次握手:建立 TCP 连接的完整流程

TCP 是面向连接的协议,传输数据前需先建立连接,该过程称为三次握手,以客户端与服务器为例,具体流程如下:

第一步:客户端发起连接请求(第一次握手)

客户端向服务器发送 TCP 报文,SYN 标志位置为 1,ACK 标志位置为 0(未收到服务器数据,无需应答)。同时,客户端生成随机初始序号填入序号字段,将自身接收缓冲区大小填入窗口大小字段,告知服务器后续数据序号起始值及自身接收能力,表达建立连接的意愿。

第二步:服务器响应连接请求(第二次握手)

服务器收到连接请求报文后,向客户端回复 TCP 报文,具体操作包括:将 SYN 标志位置为 1,示意同意建立连接;将 ACK 标志位置为 1,确认号设为客户端初始序号 + 1,告知客户端已收到连接请求;生成自身随机初始序号填入序号字段,填入自身窗口大小,同步自身序号及接收能力。

第三步:客户端确认连接(第三次握手)

客户端收到服务器响应报文后,向服务器发送 TCP 报文,将 ACK 标志位置为 1,确认号设为服务器初始序号 + 1,告知服务器已收到响应;序号字段设为客户端初始序号 + 1(第一次握手的 SYN 报文虽无数据,但占用一个序号),确认连接建立完成,双方可开始传输数据。

三次握手的核心意义

三次握手是确保双方均能正常收发数据的最少交互次数。通过三次握手,客户端确认自身能发能收,服务器也确认自身能发能收,为后续可靠数据传输奠定基础。

补充:相关系统调用

编程中触发三次握手的系统调用包括:connect(),客户端调用后发送 SYN 报文发起连接;listen(),服务器调用后进入监听状态,自动接收 SYN 报文并回复 SYN+ACK 报文;accept(),不参与握手,仅在握手完成后从已完成连接队列中取出连接,与 socket 关联用于后续数据传输。

四、四次挥手:断开 TCP 连接的完整流程

双方无数据传输时,需通过四次挥手断开 TCP 连接,确保双方均无数据残留,具体流程(以客户端主动关闭为例)及状态变化如下:

第一步:主动关闭方发送断开请求(第一次挥手)

客户端无更多数据发送时,向服务器发送 TCP 报文,FIN 标志位和 ACK 标志位均设为 1,序号字段设为客户端最后一次发送数据的最后一个字节序号 + 1,确认号字段设为服务器最后一次发送数据的最后一个字节序号 + 1。发送后客户端进入 FIN_WAIT1 状态,等待服务器应答。

第二步:被动关闭方应答(第二次挥手)

服务器收到 FIN 报文后,向客户端回复 ACK 报文,ACK 标志位设为 1,确认号设为客户端 FIN 报文序号 + 1,告知客户端已收到断开请求,正在处理剩余数据。发送后服务器进入 CLOSE_WAIT 状态,客户端收到 ACK 后进入 FIN_WAIT2 状态,等待服务器的 FIN 报文。

第三步:被动关闭方发送断开请求(第三次挥手)

服务器处理完剩余数据后,向客户端发送 FIN 报文,FIN 标志位和 ACK 标志位均设为 1,序号字段设为服务器最后一次发送数据的最后一个字节序号 + 1,确认号与上一步一致。发送后服务器进入 LAST_ACK 状态,等待客户端应答。

第四步:主动关闭方应答,连接关闭(第四次挥手)

客户端收到 FIN 报文后,向服务器回复 ACK 报文,ACK 标志位设为 1,确认号设为服务器 FIN 报文序号 + 1,告知服务器可彻底关闭连接。发送后客户端进入 TIME_WAIT 状态(持续 2MSL,即两个最大报文生存时间),服务器收到 ACK 后立即进入 CLOSED 状态,客户端等待超时后也进入 CLOSED 状态,连接彻底关闭。

TIME_WAIT 状态的作用

TIME_WAIT 状态的作用是让网络中延迟的报文、残留数据自然消散,避免新连接使用相同四元组(源 IP、目的 IP、源端口、目的端口)时,收到旧连接残留数据导致错乱。服务器短时间内频繁重启时,可能因 TIME_WAIT 状态未释放端口出现 bind error,可通过 setsockopt 函数设置地址复用缓解。

五、滑动窗口:流量控制的具体实现

滑动窗口是流量控制的具体实现,本质是发送方发送缓冲区的一部分,用于控制发送方单次发送数据量,通过窗口划分和滑动实现流量调节。

1. 滑动窗口的划分(发送端视角)

发送端发送缓冲区分为三个区域:窗口之前,为已发送且已收到确认的数据,可从缓冲区删除释放空间;窗口内部,为可直接发送但未收到确认的数据,无需等待上一批数据确认即可发送,提升效率;窗口之后,为暂时无法发送的数据,需等待窗口滑动后才能发送。

2. 滑动窗口的大小规则

滑动窗口大小由接收方窗口(接收方告知的缓冲区剩余空间)和拥塞窗口(网络当前承载能力)共同决定,实际大小为两者最小值,即滑动窗口 = min(接收方窗口,拥塞窗口)。此举可避免因网络拥堵或接收方缓冲区不足导致的数据丢失。

3. 滑动窗口的滑动过程

窗口随接收方确认不断向右滑动。例如,初始窗口大小 1000 字节,窗口内部为序号 1~1000 的数据,发送端发送后,接收方收到 1~500 字节并回复 ACK(确认号 501,窗口大小仍为 1000),发送端则将窗口之前更新为 1~500,窗口内部更新为 501~1500,窗口向右滑动 500 字节,该过程重复直至所有数据发送确认完毕。

六、丢包与超时重传

可靠传输是 TCP 核心特点,网络不可靠导致的数据丢失,通过超时重传机制解决,具体细节如下:

1. 丢包的两种情况

发送端未收到 ACK 报文,可能是数据本身未到达接收方(如网络干扰导致丢弃),也可能是数据到达但 ACK 报文返回时丢失。

2. 超时重传的机制

发送方发送数据后启动超时计时器,若计时器到期未收到 ACK,即判定数据丢失并重传。超时时间随网络状况动态调整,以 500ms 为基准,按指数退避(第一次重传后改为 1000ms,第二次 2000ms 等)。多次重传(通常 5 次)失败则判定网络异常,强制关闭连接。接收方收到重复报文时,通过序号识别并丢弃,不重复回复 ACK。

3. 快速重传

超时重传效率较低,快速重传机制可优化这一问题:接收方收到乱序报文时,持续回复相同确认号(期望收到的下一字节序号),发送方收到 3 个相同 ACK 后,立即重传对应丢失数据,无需等待超时。快速重传为优化方案,超时重传为兜底方案,确保数据最终被送达。

七、拥塞控制

流量控制关注端到端的缓冲区匹配,拥塞控制则关注整个网络状况,避免大量主机同时发送数据导致网络拥堵甚至雪崩,核心是动态调整拥塞窗口大小,具体流程如下:

1. 慢启动(探路阶段)

连接刚建立时,发送方未知网络承载能力,初始拥塞窗口较小(通常 1~2 个 MSS),每收到一个 ACK 报文,拥塞窗口翻倍(指数增长),逐步试探网络承载能力,避免初始发送量过大导致拥堵。

2. 拥塞避免(平稳增长阶段)

当拥塞窗口增长至慢启动阈值(ssthresh),退出慢启动进入拥塞避免阶段,此时拥塞窗口按线性增长(每经过一个 RTT 增加 1 个 MSS),平稳提升发送速度,避免拥堵。

3. 拥塞处理(出现拥堵后调整)

出现丢包(超时或 3 个重复 ACK)时,判定网络拥堵,将慢启动阈值设为当前拥塞窗口的一半,拥塞窗口重置为初始大小(1 MSS),重新进入慢启动阶段,循环往复适配网络状况。

4. 拥塞窗口的上限

拥塞窗口上限由网络带宽决定,达到带宽承载上限后,数据传输速度不再提升,拥塞窗口保持稳定。

八、延迟应答

延迟应答是 TCP 优化机制,用于减少纯应答报文(仅含 ACK 无数据)数量,提升网络带宽利用率。接收方收到数据后,不立即回复 ACK,而是等待几十毫秒或累计收到多个报文后,统一回复一个 ACK,将多个确认合并,减少报文数量。

例如,接收方收到 3 个报文后,等待一段时间确认无新报文,回复一个 ACK(确认号为 3 个报文最后一个字节序号 + 1),减少 2 个纯应答报文。需注意等待时间不可过长,避免发送方超时重传。

九、TCP 异常场景处理

实际网络中,TCP 连接可能遇到进程终止、机器重启、掉电、断网等异常,TCP 通过完善机制确保连接最终释放,不占用系统资源,具体场景处理如下:

1. 进程正常终止

应用进程正常终止时,操作系统内核自动接管资源,关闭进程所有 socket,向对方发送 FIN 报文,启动四次挥手,优雅关闭连接,确保双方无数据残留。

2. 机器重启

机器正常重启时,内核清理所有 TCP 连接资源,重启后认为原有连接失效。若对方继续发送数据,重启后的机器会回复 RST 报文强制断开连接,对方收到 RST 后立即关闭连接。

3. 机器掉电、断网

掉电、断网时机器无法收发报文,分两种情况处理:

(1)对端持续发送数据:断网机器无法接收数据和回复 ACK,内核会持续重传未发送数据,重传次数达上限或保活超时后,判定连接失效并关闭;对端因未收到 ACK 持续重传,超时后关闭连接;网络恢复后,断网机器收到旧连接数据,会回复 RST 强制断开。

(2)对端没有发送数据:依靠保活机制,发送方定期发送空探测报文检测连接状态,断网机器无法应答,发送方保活超时后,判定连接失效并关闭。

异常处理总结

TCP 通过超时、重传、RST 复位、保活机制等,确保无论何种异常,连接最终都会被释放,体现其可靠性。

相关推荐
chen_ever2 小时前
从网络基础到吃透 Linux 高并发 I/O 核心(epoll+零拷贝 完整版)
linux·网络·c++·后端
情绪雪3 小时前
TCP/IP 模型
网络·网络协议·tcp/ip
bukeyiwanshui3 小时前
20260407 网络时间设置
网络
@insist1233 小时前
网络工程师-因特网与网络互联(一):IPv4 协议精讲,从分类地址到子网划分
网络·网络工程师·软考·软件水平考试
taxunjishu3 小时前
Profinet转MODBUS TCP在精细化工塔讯工业自动化中的应用方案
网络·网络协议
hzxpaipai3 小时前
英语+越南语网站架构设计:派迪科技多语言建站实践解析
网络·科技·物联网·网络安全·https
安科瑞小许3 小时前
35kV变电站的“智慧大脑”——综合自动化系统
大数据·网络·变电站·零碳园区
yy_xzz3 小时前
【Linux开发】多线程并发服务器(网络编程+多线程+线程同步实现的聊天服务器和客户端)
linux·服务器·网络
OPHKVPS3 小时前
网络犯罪分子锁定个人AI助手:OpenClaw配置遭信息窃取恶意软件攻击
网络