谈谈对传输层协议TCP的理解

TCP(Transmission Control Protocol,传输控制协议)是 TCP/IP 协议簇中传输层 的核心协议,专为实现可靠、有序、面向连接的端到端数据传输设计,广泛应用于对数据完整性要求高的场景(如 HTTP、FTP、SMTP 等应用层协议均基于 TCP)。下面从核心特性、工作原理、关键机制三方面详细拆解:

一、TCP 的核心特性

  1. 面向连接TCP 通信前必须先建立 "连接"(三次握手),通信结束后必须释放连接(四次挥手),类似打电话:先拨号确认对方接听,再通话,最后挂电话。对比 UDP(无连接):UDP 无需建立连接,直接发数据,类似发短信,无法确认对方是否收到。

  2. 可靠传输 TCP 通过一系列机制保证数据无丢失、无重复、按序到达

    • 确认应答(ACK):接收方收到数据后,必须向发送方返回 "确认报文",发送方若未收到 ACK 则重传;
    • 超时重传:发送方发送数据后启动定时器,超时未收到 ACK 则重新发送;
    • 差错检测:通过校验和检测数据是否损坏,损坏则丢弃并要求重传;
    • 流量控制:避免发送方发得太快,接收方处理不过来(滑动窗口机制);
    • 拥塞控制:避免发送方发得太快,导致网络拥堵(慢启动、拥塞避免等算法)。
  3. 字节流服务TCP 把应用层传递的大数据拆分成若干 "报文段"(Segment)传输,接收方再按顺序拼接还原成完整字节流,对应用层隐藏拆分 / 拼接细节。(注:TCP 不保留报文边界,比如应用层连续发两次 100 字节,TCP 可能合并成 200 字节发送,也可能拆成更小片段,接收方需自行处理边界识别)

  4. 全双工通信建立连接后,通信双方可同时发送和接收数据(类似双向车道),无需等待对方发送完毕。

二、TCP 的工作流程(三次握手 + 数据传输 + 四次挥手)

1. 连接建立:三次握手(Three-way Handshake)

目的:同步通信双方的序列号和确认号,协商窗口大小,确保双方收发能力正常。

  • 第一次握手(SYN):客户端→服务器,发送 SYN 报文(同步序列编号),声明自己的初始序列号(ISN),请求建立连接;
  • 第二次握手(SYN+ACK):服务器→客户端,发送 SYN+ACK 报文,确认客户端的 SYN(ACK = 客户端 ISN+1),同时声明自己的初始序列号;
  • 第三次握手(ACK):客户端→服务器,发送 ACK 报文,确认服务器的 SYN(ACK = 服务器 ISN+1),连接正式建立。

**为什么需要三次?**如果只有两次握手,服务器无法确认客户端是否能收到自己的 SYN+ACK(可能客户端的 SYN 延迟到达,服务器建立连接后,客户端却没收到确认,导致资源浪费),三次握手能确保双方都确认 "对方能收能发"。

2. 数据传输:基于滑动窗口的可靠传输
  • 发送方维护 "发送窗口":表示当前可发送但未确认的字节范围,窗口内的数据可连续发送(无需等一个确认再发下一个),提高传输效率;
  • 接收方维护 "接收窗口":表示当前可接收的字节范围,通过 ACK 报文告知发送方窗口大小,实现流量控制;
  • 按序重组:接收方按序列号拼接报文段,若中间某段丢失(比如收到 1-100、201-300,缺 101-200),则对已收到的后续数据暂存,等待丢失段重传后再拼接。
3. 连接释放:四次挥手(Four-way Wavehandshake)

目的:确保双方都已完成数据传输,安全释放连接资源。

  • 第一次挥手(FIN):主动关闭方→被动关闭方,发送 FIN 报文(终止连接),表示自己已无数据要发送;
  • 第二次挥手(ACK):被动关闭方→主动关闭方,发送 ACK 报文,确认收到 FIN(此时被动关闭方仍可发送剩余数据);
  • 第三次挥手(FIN):被动关闭方→主动关闭方,发送 FIN 报文,表示自己也无数据要发送;
  • 第四次挥手(ACK):主动关闭方→被动关闭方,发送 ACK 报文,确认收到 FIN,等待 2MSL(最大报文段生存时间)(提问为什么需要等待2MSL?(答案再最后面))后释放连接。

**为什么需要四次?**因为 TCP 是全双工通信,关闭连接时需要分别关闭 "发送方向" 和 "接收方向":第一次 FIN 关闭主动方的发送方向,第二次 ACK 确认;第三次 FIN 关闭被动方的发送方向,第四次 ACK 确认,因此需要四次。

三、TCP 的关键机制(保证可靠性的核心)

1. 流量控制(Flow Control)
  • 作用:避免接收方缓冲区溢出(发送方速度 > 接收方处理速度);
  • 实现:接收方通过 TCP 报文头部的 "窗口大小" 字段,告知发送方自己当前可用的缓冲区大小,发送方根据该值调整发送速率;
  • 核心:滑动窗口(Sliding Window)------ 窗口大小动态变化,接收方缓冲区空闲越多,窗口越大,发送方发送越快;缓冲区满则窗口为 0,发送方停止发送。
2. 拥塞控制(Congestion Control)
  • 作用:避免发送方速度 > 网络承载能力(导致网络拥堵、丢包);
  • 核心算法:
    • 慢启动(Slow Start):连接建立后,发送方从小窗口开始(初始窗口 = 1 个报文段),每收到一个 ACK,窗口大小翻倍,直到达到 "慢启动阈值";
    • 拥塞避免(Congestion Avoidance):达到阈值后,窗口大小每次加 1(线性增长),避免指数增长导致拥堵;
    • 快速重传(Fast Retransmit):若接收方收到乱序报文,立即发送重复 ACK,发送方收到 3 个重复 ACK 后,无需等待超时就重传丢失报文;
    • 快速恢复(Fast Recovery):重传后,窗口大小调整为慢启动阈值的一半,进入拥塞避免阶段,无需重新慢启动。
3. 超时重传与重传计时器
  • 发送方为每个发送的报文段启动计时器,超时时间(RTO)根据 "往返时间(RTT)" 动态调整(RTT 是数据发送到收到 ACK 的时间);
  • 若超时未收到 ACK,立即重传该报文段,同时调整 RTO(避免因网络延迟导致误判丢包)。
4. 校验和(Checksum)
  • TCP 报文头部和数据部分都会计算校验和,接收方收到后重新计算,若与报文携带的校验和不一致,说明数据损坏,直接丢弃并要求重传。

四、TCP 的适用场景

  • 对可靠性要求高的场景:网页浏览(HTTP/HTTPS)、文件传输(FTP)、邮件收发(SMTP/POP3)、远程登录(SSH/Telnet);
  • 不适用场景:实时性要求高的场景(如视频通话、游戏)------TCP 的重传机制会导致延迟,这类场景通常用 UDP + 应用层可靠机制实现。

五、TCP 报文结构(简要)

TCP 报文由 "头部 + 数据" 组成,头部固定 20 字节(可选字段最多扩展到 60 字节),关键字段:

  • 源端口 / 目的端口:标识通信的应用程序(如 HTTP 用 80 端口);
  • 序列号(Seq):当前报文段数据的起始字节编号;
  • 确认号(Ack):期望收到的下一个报文段的序列号(即已收到 Ack-1 之前的所有数据);
  • 窗口大小:接收方当前可用的缓冲区大小(流量控制核心);
  • 标志位(Flags):SYN(同步)、ACK(确认)、FIN(终止)、RST(重置连接)、PSH(推送数据)、URG(紧急数据)。

六、问题解答

1、再TCP四次挥手士主动关闭方为什么需要等待2MSL(或者为什么主动关闭方有一个TIME-WAIT的状态)?

TCP 设计 TIME-WAIT 状态并设置 2MSL 时长,本质是为了解决两个关键问题:确保连接可靠关闭防止旧连接的过期报文干扰新连接,这两个问题都与 TCP 报文在网络中的 "生命周期" 直接相关。

1. 确保连接能 "可靠关闭":给最后一个 ACK 报文 "容错时间"

TCP 四次挥手的最终关闭流程是:

  • 主动关闭方(如客户端)发送 FIN 报文(请求关闭)→ 被动关闭方(如服务器)回复 FIN+ACK(同意关闭,并请求自己的关闭)→ 主动关闭方回复 ACK(确认收到服务器的关闭请求)。

这里的关键风险是:最后一个 ACK 报文可能丢失(比如网络波动)。

  • 若 ACK 丢失,被动关闭方(服务器)会因为没收到确认,在超时后重传 FIN 报文(因为服务器认为自己的 FIN 没被收到)。
  • 主动关闭方(客户端)在 TIME-WAIT 状态下(持续 2MSL),就能收到这个重传的 FIN 报文,此时会重新发送 ACK 并重置 2MSL 计时器 ------ 确保服务器最终能收到确认,顺利进入 CLOSED 状态。

如果没有 2MSL 的等待:

  • 客户端发送 ACK 后直接关闭,若 ACK 丢失,服务器会一直重传 FIN 却收不到回应,最终因超时进入错误关闭状态(连接未正常释放)。
2. 防止 "旧连接的过期报文" 干扰 "新连接":给旧报文 "消亡时间"

TCP 连接的唯一标识是 "源 IP + 源端口 + 目的 IP + 目的端口"(四元组)。实际场景中,同一台机器可能在短时间内用相同四元组建立新连接(比如客户端断开后立即重连服务器,端口复用)。

此时的风险是:上一个连接中残留的 "过期报文"(因网络延迟未及时到达)可能闯入新连接

  • 旧报文的序号属于上一个连接的序号范围,若新连接恰好使用相同四元组,TCP 会误认为这是新连接的正常报文,导致数据错乱。

2MSL 的等待正是为了避免这种情况:

  • MSL 是 "报文在网络中能存活的最长时间"(比如 1 分钟),意味着旧连接的任何报文最多在网络中跑 1 分钟就会被丢弃。
  • 2MSL 则覆盖了 "旧报文从主动方到被动方,再从被动方返回主动方" 的最长往返时间 ------ 确保在 TIME-WAIT 结束时,网络中所有属于上一个连接的报文都已彻底消失。

如果没有 2MSL 的等待:

  • 新连接建立后,可能收到上一个连接的旧报文,TCP 会根据序号处理(若序号在新连接的接收窗口内),导致数据错误或连接异常。
总结:2MSL 是 "双重保险"
  • 对 "连接关闭":用 2MSL 确保最后一个 ACK 能被对方收到(或重传后收到),避免被动方卡在关闭流程中。
  • 对 "新连接安全":用 2MSL 确保旧连接的所有报文已从网络中消亡,避免干扰复用相同四元组的新连接。

这也是为什么 TIME-WAIT 状态只能由 "主动关闭方" 承担(被动关闭方在收到最后一个 ACK 后直接进入 CLOSED)------ 因为主动关闭方是最后一个发送报文的角色,需要对 "报文是否送达" 和 "旧报文是否清除" 负责。

相关推荐
全栈工程师修炼指南2 小时前
Nginx | HTTPS 加密传输:Nginx 反向代理与上游服务 SSL 双向认证实践
网络·数据库·nginx·https·ssl
秋深枫叶红2 小时前
嵌入式第三十八篇——linux系统编程——IPC进程间通信
linux·服务器·网络·学习
缺的不是资料,是学习的心2 小时前
vmware虚拟机ens33拿不到ip,已经开启dhcp了
网络·网络协议·tcp/ip
Boop_wu2 小时前
[Java EE] 网络原理(2) http
网络·网络协议·http
fulufulucode2 小时前
【网络协议】HTTPS相关知识详细梳理
网络·网络协议
yenggd3 小时前
华为SRv6 BE跨域配置案例
运维·网络·计算机网络·华为
LCG米3 小时前
基于LoRa的远距离低功耗农业传感器网络设计与实现(SX1278+STM32L071)
网络·stm32·php
thginWalker3 小时前
从打字机效果实现详解整包/流式传输、长/短连接、SSE、Streamable-HTTP、长轮询、WebSocket
网络协议
大布布将军3 小时前
⚡️编排的艺术:BFF 的核心职能——数据聚合与 HTTP 请求
前端·网络·网络协议·程序人生·http·node.js·改行学it