TCP 原理详解:从三次握手到拥塞控制

1. 引言

TCP(Transmission Control Protocol,传输控制协议)是互联网协议栈中最重要的传输层协议之一。它位于 IP 层之上,为应用层提供可靠、面向连接、基于字节流的通信服务。无论是浏览网页、发送邮件、传输文件,还是视频通话,绝大多数应用都依赖 TCP 来保证数据能够完整、有序地到达对端。

本文将从 TCP 的报文段结构出发,系统讲解连接管理(三次握手与四次挥手)、可靠传输机制、流量控制与拥塞控制等核心原理,帮助读者建立对 TCP 的整体认知。

2. TCP 报文段结构

在深入原理之前,先了解 TCP 报文段的基本格式。TCP 报文段由首部 和数据两部分组成,首部默认长度为 20 字节(不含选项字段)。

字段 长度 说明
源端口 / 目的端口 各 2 字节 标识通信的进程
序号(Sequence Number) 4 字节 本报文段数据首字节的序号
确认号(Acknowledgment Number) 4 字节 期望收到对方下一个字节的序号
数据偏移 4 位 首部长度
保留 6 位 保留未用
标志位 6 位 URG、ACK、PSH、RST、SYN、FIN
窗口(Window) 2 字节 接收方的接收窗口大小
校验和 2 字节 校验首部与数据
紧急指针 2 字节 仅 URG 置位时有效

其中,六个标志位是理解 TCP 状态机的关键:

  • SYN:同步序号,用于建立连接。
  • ACK:确认序号有效。
  • FIN:释放连接。
  • RST:重置连接。
  • PSH:立即交付应用层。
  • URG:紧急数据。

3. 连接管理:三次握手与四次挥手

3.1 三次握手建立连接

TCP 建立连接需要经过三次报文交换,称为三次握手。其目的是确认双方的收发能力都正常,并同步初始序号。
服务端 客户端 服务端 客户端 #mermaid-svg-hdqE4qjulT8mSNL7{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-hdqE4qjulT8mSNL7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-hdqE4qjulT8mSNL7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-hdqE4qjulT8mSNL7 .error-icon{fill:#552222;}#mermaid-svg-hdqE4qjulT8mSNL7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hdqE4qjulT8mSNL7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-hdqE4qjulT8mSNL7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hdqE4qjulT8mSNL7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hdqE4qjulT8mSNL7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-hdqE4qjulT8mSNL7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hdqE4qjulT8mSNL7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hdqE4qjulT8mSNL7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hdqE4qjulT8mSNL7 .marker.cross{stroke:#333333;}#mermaid-svg-hdqE4qjulT8mSNL7 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hdqE4qjulT8mSNL7 p{margin:0;}#mermaid-svg-hdqE4qjulT8mSNL7 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-hdqE4qjulT8mSNL7 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-hdqE4qjulT8mSNL7 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-hdqE4qjulT8mSNL7 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-hdqE4qjulT8mSNL7 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-hdqE4qjulT8mSNL7 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-hdqE4qjulT8mSNL7 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-hdqE4qjulT8mSNL7 .sequenceNumber{fill:white;}#mermaid-svg-hdqE4qjulT8mSNL7 #sequencenumber{fill:#333;}#mermaid-svg-hdqE4qjulT8mSNL7 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-hdqE4qjulT8mSNL7 .messageText{fill:#333;stroke:none;}#mermaid-svg-hdqE4qjulT8mSNL7 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-hdqE4qjulT8mSNL7 .labelText,#mermaid-svg-hdqE4qjulT8mSNL7 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-hdqE4qjulT8mSNL7 .loopText,#mermaid-svg-hdqE4qjulT8mSNL7 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-hdqE4qjulT8mSNL7 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-hdqE4qjulT8mSNL7 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-hdqE4qjulT8mSNL7 .noteText,#mermaid-svg-hdqE4qjulT8mSNL7 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-hdqE4qjulT8mSNL7 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-hdqE4qjulT8mSNL7 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-hdqE4qjulT8mSNL7 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-hdqE4qjulT8mSNL7 .actorPopupMenu{position:absolute;}#mermaid-svg-hdqE4qjulT8mSNL7 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-hdqE4qjulT8mSNL7 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-hdqE4qjulT8mSNL7 .actor-man circle,#mermaid-svg-hdqE4qjulT8mSNL7 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-hdqE4qjulT8mSNL7 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} SYN=1, seq=x(SYN_SENT)SYN=1, ACK=1, seq=y, ack=x+1(SYN_RCVD)ACK=1, seq=x+1, ack=y+1(ESTABLISHED)

具体过程如下:

  1. 第一次握手 :客户端发送 SYN 报文,初始序号为 x,进入 SYN_SENT 状态。
  2. 第二次握手 :服务端收到后,回复 SYN+ACK 报文,自己的序号为 y,确认号为 x+1,进入 SYN_RCVD 状态。
  3. 第三次握手 :客户端收到后,发送 ACK 报文,确认号为 y+1,双方进入 ESTABLISHED 状态。

为什么需要三次握手? 主要是为了防止已失效的连接请求突然又传到服务端,导致服务端误开连接、浪费资源。三次握手能让双方确认彼此的序号同步,避免历史报文造成混乱。

3.2 四次挥手释放连接

TCP 连接是全双工的,因此释放连接需要四次挥手,双方各自关闭一个方向的数据传输。
被动关闭方 主动关闭方 被动关闭方 主动关闭方 #mermaid-svg-T55MPGm1CZ8ZqMbu{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-T55MPGm1CZ8ZqMbu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-T55MPGm1CZ8ZqMbu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-T55MPGm1CZ8ZqMbu .error-icon{fill:#552222;}#mermaid-svg-T55MPGm1CZ8ZqMbu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-T55MPGm1CZ8ZqMbu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-T55MPGm1CZ8ZqMbu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-T55MPGm1CZ8ZqMbu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-T55MPGm1CZ8ZqMbu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-T55MPGm1CZ8ZqMbu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-T55MPGm1CZ8ZqMbu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-T55MPGm1CZ8ZqMbu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-T55MPGm1CZ8ZqMbu .marker.cross{stroke:#333333;}#mermaid-svg-T55MPGm1CZ8ZqMbu svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-T55MPGm1CZ8ZqMbu p{margin:0;}#mermaid-svg-T55MPGm1CZ8ZqMbu .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-T55MPGm1CZ8ZqMbu text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-T55MPGm1CZ8ZqMbu .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-T55MPGm1CZ8ZqMbu .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-T55MPGm1CZ8ZqMbu .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-T55MPGm1CZ8ZqMbu .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-T55MPGm1CZ8ZqMbu #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-T55MPGm1CZ8ZqMbu .sequenceNumber{fill:white;}#mermaid-svg-T55MPGm1CZ8ZqMbu #sequencenumber{fill:#333;}#mermaid-svg-T55MPGm1CZ8ZqMbu #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-T55MPGm1CZ8ZqMbu .messageText{fill:#333;stroke:none;}#mermaid-svg-T55MPGm1CZ8ZqMbu .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-T55MPGm1CZ8ZqMbu .labelText,#mermaid-svg-T55MPGm1CZ8ZqMbu .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-T55MPGm1CZ8ZqMbu .loopText,#mermaid-svg-T55MPGm1CZ8ZqMbu .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-T55MPGm1CZ8ZqMbu .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-T55MPGm1CZ8ZqMbu .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-T55MPGm1CZ8ZqMbu .noteText,#mermaid-svg-T55MPGm1CZ8ZqMbu .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-T55MPGm1CZ8ZqMbu .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-T55MPGm1CZ8ZqMbu .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-T55MPGm1CZ8ZqMbu .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-T55MPGm1CZ8ZqMbu .actorPopupMenu{position:absolute;}#mermaid-svg-T55MPGm1CZ8ZqMbu .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-T55MPGm1CZ8ZqMbu .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-T55MPGm1CZ8ZqMbu .actor-man circle,#mermaid-svg-T55MPGm1CZ8ZqMbu line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-T55MPGm1CZ8ZqMbu :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} FIN=1, seq=u(FIN_WAIT_1)ACK=1, ack=u+1(CLOSE_WAIT)FIN=1, seq=v(LAST_ACK)ACK=1, ack=v+1(TIME_WAIT)

  1. 第一次挥手 :主动方发送 FIN 报文,表示不再发送数据,进入 FIN_WAIT_1。
  2. 第二次挥手 :被动方回复 ACK,进入 CLOSE_WAIT;主动方收到后进入 FIN_WAIT_2。
  3. 第三次挥手 :被动方处理完数据后,发送 FIN 报文,进入 LAST_ACK。
  4. 第四次挥手 :主动方回复 ACK,进入 TIME_WAIT,等待 2MSL 后关闭。

为什么需要 TIME_WAIT? 一是确保最后一个 ACK 能到达对端(若丢失可重传);二是让旧连接的报文在网络中自然消失,避免干扰新连接。

4. 可靠传输机制

TCP 的可靠性建立在序号、确认、重传三大机制之上。

4.1 序号与确认

TCP 将数据视为字节流,每个字节都有唯一的序号。发送方按序号发送数据,接收方收到后返回确认号,表示「该序号之前的数据都已正确收到」。

4.2 超时重传

发送方为每个已发送但未确认的报文启动定时器。若超时仍未收到 ACK,则重传该报文。超时时间(RTO)根据往返时间(RTT)动态计算,避免固定值导致效率低下。

4.3 快速重传

当接收方收到失序报文时,会立即重复发送对最后一个有序字节的 ACK。发送方连续收到 3 个重复 ACK 时,不等超时即重传丢失的报文,从而加快恢复速度。

4.4 选择性确认(SACK)

SACK 选项允许接收方告知发送方「哪些区间已收到」,发送方只需重传真正丢失的报文段,避免不必要的重传,提升带宽利用率。

5. 流量控制

流量控制的目的是防止发送方发送过快,导致接收方缓冲区溢出 。TCP 通过滑动窗口机制实现。

接收方在每次 ACK 中携带自己的接收窗口(rwnd) ,告知发送方「我还能接收多少字节」。发送方的发送窗口取 min(拥塞窗口 cwnd, 接收窗口 rwnd)。
#mermaid-svg-3k1QLkOkALCpHrc9{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-3k1QLkOkALCpHrc9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-3k1QLkOkALCpHrc9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-3k1QLkOkALCpHrc9 .error-icon{fill:#552222;}#mermaid-svg-3k1QLkOkALCpHrc9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-3k1QLkOkALCpHrc9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-3k1QLkOkALCpHrc9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-3k1QLkOkALCpHrc9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-3k1QLkOkALCpHrc9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-3k1QLkOkALCpHrc9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-3k1QLkOkALCpHrc9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-3k1QLkOkALCpHrc9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-3k1QLkOkALCpHrc9 .marker.cross{stroke:#333333;}#mermaid-svg-3k1QLkOkALCpHrc9 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-3k1QLkOkALCpHrc9 p{margin:0;}#mermaid-svg-3k1QLkOkALCpHrc9 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-3k1QLkOkALCpHrc9 .cluster-label text{fill:#333;}#mermaid-svg-3k1QLkOkALCpHrc9 .cluster-label span{color:#333;}#mermaid-svg-3k1QLkOkALCpHrc9 .cluster-label span p{background-color:transparent;}#mermaid-svg-3k1QLkOkALCpHrc9 .label text,#mermaid-svg-3k1QLkOkALCpHrc9 span{fill:#333;color:#333;}#mermaid-svg-3k1QLkOkALCpHrc9 .node rect,#mermaid-svg-3k1QLkOkALCpHrc9 .node circle,#mermaid-svg-3k1QLkOkALCpHrc9 .node ellipse,#mermaid-svg-3k1QLkOkALCpHrc9 .node polygon,#mermaid-svg-3k1QLkOkALCpHrc9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-3k1QLkOkALCpHrc9 .rough-node .label text,#mermaid-svg-3k1QLkOkALCpHrc9 .node .label text,#mermaid-svg-3k1QLkOkALCpHrc9 .image-shape .label,#mermaid-svg-3k1QLkOkALCpHrc9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-3k1QLkOkALCpHrc9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-3k1QLkOkALCpHrc9 .rough-node .label,#mermaid-svg-3k1QLkOkALCpHrc9 .node .label,#mermaid-svg-3k1QLkOkALCpHrc9 .image-shape .label,#mermaid-svg-3k1QLkOkALCpHrc9 .icon-shape .label{text-align:center;}#mermaid-svg-3k1QLkOkALCpHrc9 .node.clickable{cursor:pointer;}#mermaid-svg-3k1QLkOkALCpHrc9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-3k1QLkOkALCpHrc9 .arrowheadPath{fill:#333333;}#mermaid-svg-3k1QLkOkALCpHrc9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-3k1QLkOkALCpHrc9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-3k1QLkOkALCpHrc9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3k1QLkOkALCpHrc9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-3k1QLkOkALCpHrc9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3k1QLkOkALCpHrc9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-3k1QLkOkALCpHrc9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-3k1QLkOkALCpHrc9 .cluster text{fill:#333;}#mermaid-svg-3k1QLkOkALCpHrc9 .cluster span{color:#333;}#mermaid-svg-3k1QLkOkALCpHrc9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-3k1QLkOkALCpHrc9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-3k1QLkOkALCpHrc9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-3k1QLkOkALCpHrc9 .icon-shape,#mermaid-svg-3k1QLkOkALCpHrc9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-3k1QLkOkALCpHrc9 .icon-shape p,#mermaid-svg-3k1QLkOkALCpHrc9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-3k1QLkOkALCpHrc9 .icon-shape .label rect,#mermaid-svg-3k1QLkOkALCpHrc9 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-3k1QLkOkALCpHrc9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-3k1QLkOkALCpHrc9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-3k1QLkOkALCpHrc9 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 发送窗口 = min(cwnd, rwnd)
ACK + rwnd
发送方
接收方

一个典型问题是窗口零通告 :当接收方缓冲区满时,rwnd 变为 0,发送方停止发送。为防止死锁,发送方会定期发送 1 字节的探测报文,询问接收方窗口是否恢复。

6. 拥塞控制

拥塞控制是全局性的,目的是避免过多数据注入网络导致路由器拥塞。TCP 采用四种算法配合工作。

6.1 慢启动

连接建立后,拥塞窗口 cwnd 从 1 个 MSS 开始,每收到一个 ACK 就加 1,呈指数增长 。当 cwnd 达到慢启动阈值 ssthresh 时,转入拥塞避免。

6.2 拥塞避免

cwnd 每经过一个 RTT 只增加 1 个 MSS,呈线性增长,增长较为平缓。

6.3 快重传与快恢复

当发送方收到 3 个重复 ACK 时:

  • 将 ssthresh 减半;
  • cwnd 设为 ssthresh,进入快恢复;
  • 之后按拥塞避免的线性方式增长。

若发生超时,则 ssthresh 减半,cwnd 重置为 1,重新进入慢启动。
#mermaid-svg-p3cosR286FmvqlKm{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-p3cosR286FmvqlKm .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-p3cosR286FmvqlKm .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-p3cosR286FmvqlKm .error-icon{fill:#552222;}#mermaid-svg-p3cosR286FmvqlKm .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-p3cosR286FmvqlKm .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-p3cosR286FmvqlKm .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-p3cosR286FmvqlKm .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-p3cosR286FmvqlKm .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-p3cosR286FmvqlKm .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-p3cosR286FmvqlKm .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-p3cosR286FmvqlKm .marker{fill:#333333;stroke:#333333;}#mermaid-svg-p3cosR286FmvqlKm .marker.cross{stroke:#333333;}#mermaid-svg-p3cosR286FmvqlKm svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-p3cosR286FmvqlKm p{margin:0;}#mermaid-svg-p3cosR286FmvqlKm .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-p3cosR286FmvqlKm .cluster-label text{fill:#333;}#mermaid-svg-p3cosR286FmvqlKm .cluster-label span{color:#333;}#mermaid-svg-p3cosR286FmvqlKm .cluster-label span p{background-color:transparent;}#mermaid-svg-p3cosR286FmvqlKm .label text,#mermaid-svg-p3cosR286FmvqlKm span{fill:#333;color:#333;}#mermaid-svg-p3cosR286FmvqlKm .node rect,#mermaid-svg-p3cosR286FmvqlKm .node circle,#mermaid-svg-p3cosR286FmvqlKm .node ellipse,#mermaid-svg-p3cosR286FmvqlKm .node polygon,#mermaid-svg-p3cosR286FmvqlKm .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-p3cosR286FmvqlKm .rough-node .label text,#mermaid-svg-p3cosR286FmvqlKm .node .label text,#mermaid-svg-p3cosR286FmvqlKm .image-shape .label,#mermaid-svg-p3cosR286FmvqlKm .icon-shape .label{text-anchor:middle;}#mermaid-svg-p3cosR286FmvqlKm .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-p3cosR286FmvqlKm .rough-node .label,#mermaid-svg-p3cosR286FmvqlKm .node .label,#mermaid-svg-p3cosR286FmvqlKm .image-shape .label,#mermaid-svg-p3cosR286FmvqlKm .icon-shape .label{text-align:center;}#mermaid-svg-p3cosR286FmvqlKm .node.clickable{cursor:pointer;}#mermaid-svg-p3cosR286FmvqlKm .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-p3cosR286FmvqlKm .arrowheadPath{fill:#333333;}#mermaid-svg-p3cosR286FmvqlKm .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-p3cosR286FmvqlKm .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-p3cosR286FmvqlKm .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-p3cosR286FmvqlKm .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-p3cosR286FmvqlKm .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-p3cosR286FmvqlKm .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-p3cosR286FmvqlKm .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-p3cosR286FmvqlKm .cluster text{fill:#333;}#mermaid-svg-p3cosR286FmvqlKm .cluster span{color:#333;}#mermaid-svg-p3cosR286FmvqlKm div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-p3cosR286FmvqlKm .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-p3cosR286FmvqlKm rect.text{fill:none;stroke-width:0;}#mermaid-svg-p3cosR286FmvqlKm .icon-shape,#mermaid-svg-p3cosR286FmvqlKm .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-p3cosR286FmvqlKm .icon-shape p,#mermaid-svg-p3cosR286FmvqlKm .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-p3cosR286FmvqlKm .icon-shape .label rect,#mermaid-svg-p3cosR286FmvqlKm .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-p3cosR286FmvqlKm .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-p3cosR286FmvqlKm .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-p3cosR286FmvqlKm :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} cwnd >= ssthresh
3 个重复 ACK
超时
慢启动

cwnd 指数增长
拥塞避免

cwnd 线性增长
快重传 + 快恢复

7. 常见问题与优化

  • Nagle 算法:合并小报文减少网络开销,但可能增加延迟,实时应用可关闭。
  • 延迟确认:接收方延迟一段时间再合并确认,减少 ACK 数量。
  • TCP_NODELAY:在 socket 层面关闭 Nagle 算法,降低交互式应用的延迟。
  • Keep-Alive:定期发送探测报文,检测对端是否存活。

8. 总结

TCP 通过三次握手 建立可靠连接,用序号、确认与重传 保证数据不丢不乱,用滑动窗口 实现流量控制,用慢启动、拥塞避免、快重传与快恢复应对网络拥塞。理解这些核心机制,是排查网络问题、优化应用性能的基础。

希望本文能帮助你建立起对 TCP 原理的系统认识。如果你对某个机制想深入了解,欢迎在评论区留言讨论。

相关推荐
木白CPP44 分钟前
USB(一): USB 概述&&介绍
linux·网络·嵌入式硬件
可乐鸡翅yeah_1 小时前
AES‑128 加密 M3U8,IV 初始化向量新手容易踩坑
前端·网络·数据库·ffmpeg·音视频·m3u8在线
HEJOO91 小时前
指针与结构体:C 语言进阶核心详解
c语言·开发语言·网络
en.en..1 小时前
IO 多路复用:select、poll、epoll 核心函数解析
网络
我就是不信1 小时前
TCP/IP 网络编程:从入门到实战
网络·网络协议·tcp/ip
沫璃染墨2 小时前
《Qt从零入门系列(十二):Qt文件操作详解——从QFile读写到QFileInfo与记事本实战》
开发语言·网络·c++·qt·交互·信号处理·文件
梦帮科技3 小时前
推测解码(Speculative Decoding)与 Draft-Target 双核协同:接受率判据、树状验证与两倍吞吐无损加速
网络·人工智能·深度学习·神经网络·线性代数·矩阵·架构
骑着蜗牛撵大象3273 小时前
Agent 打字机是怎么来的:SSE 与 WebSocket 打通实时响应与中间状态
网络·websocket·网络协议·agent·sse·实时通信·流式输出
Frank_refuel4 小时前
分布式RPC框架实战(二):服务端模块划分与底层设计
分布式·网络协议·rpc