文章目录
一、运输层概述
二、UDP和TCP的对比
三、TCP
四、结语
一、运输层概述
1.1 进程间基于网络的通信


1.2 TCP/IP体系结构运输层中的两个重要协议


1.3 运输层端口号、复用与分用的概念




二、UDP和TCP的对比
2.1 无连接的UDP和面向连接的TCP

2.2 UDP和TCP对单播、多播和广播的支持情况

2.3 UDP和TCP对应用层报文的处理

2.4 UDP和TCP对数据传输可靠性的支持情况

2.5 UDP首部和TCP首部的对比

对比总结:

三、TCP
3.1 TCP报文段的首部格式













3.2 TCP的运输连接管理

3.2.1 "三次握手"建立TCP连接

"三次握手"完整流程:
- 第一次握手(客户端 → 服务端)
客户端发送 SYN 报文,携带客户端初始序列号 ISN(c)
→ 客户端进入 SYN_SENT 状态
- 第二次握手(服务端 → 客户端)
服务端收到 SYN,回复:
SYN + ACK
-
SYN:服务端也要同步连接
-
ACK:确认客户端报文,确认号 = 客户端ISN + 1
携带服务端初始序列号 ISN(s)
→ 服务端进入 SYN_RCVD 状态
- 第三次握手(客户端 → 服务端)
客户端收到 SYN+ACK,发送 ACK 报文
确认号 = 服务端ISN + 1
→ 客户端进入 ESTABLISHED(已连接)
→ 服务端收到此 ACK 后,也进入 ESTABLISHED
连接建立完成,开始传输数据。
注:
为什么是三次,不是两次?
- 两次握手隐患
服务端收到客户端SYN就直接建立连接,
如果客户端失效的延迟SYN报文到达服务端,服务端会错误建立无效连接,浪费资源(半开连接)。
- 三次握手
需要客户端最后一次ACK确认,避免过期无效连接,保证双方收发都正常。
3.2.2 "四次挥手"释放TCP连接
四次挥手流程:
- 第一次挥手:主动方 → 被动方(FIN)
主动关闭方(客户端/服务端都行)发送 FIN,表示:我不再发数据了
进入: FIN_WAIT_1
- 第二次挥手:被动方 → 主动方(ACK)
被动方收到 FIN,回复 ACK 确认关闭请求
此时:主动方不能发数据,但还能收数据(半关闭状态)
主动方进入: FIN_WAIT_2
被动方进入: CLOSE_WAIT
- 第三次挥手:被动方 → 主动方(FIN)
被动方数据全部发送完毕,发送 FIN,表示:我也不发数据了
进入: LAST_ACK
- 第四次挥手:主动方 → 被动方(ACK)
主动方收到 FIN,回复 ACK
-
被动方收到 ACK:直接进入 CLOSED 彻底断开
-
主动方等待 2MSL 时长后,进入 CLOSED
关键问题:
- 为什么建立是三次,断开要四次?
建连:SYN + ACK 可以合并,一次报文完成
断连:被动方收到 FIN 后,可能还有剩余数据要发,不能立刻发FIN,必须先发ACK,等数据发完再发FIN,因此多一步
- 为什么主动方要等 2MSL?
保证最后一次 ACK 能被对方收到
防止残留延迟报文,避免下次连接受干扰
3.3 TCP的流量控制
3.3.1 TCP流量控制的基本概念
- TCP为应用程序提供了流量控制(Flow Control)机制,以解决因发送方发送数据太快而导致接收方来不及接收,造成接收方的接收缓存溢出的情况。
- 流量控制的基本方法:接收方根据自己的接收能力(接收缓存的可用空间大小)控制发送方的发送速率。
3.3.2 TCP的流量控制方法
TCP 流量控制(Flow Control)的核心目的,是匹配发送方和接收方的处理速度,防止接收方缓冲区溢出,导致数据丢失。
主要方法有以下三种:
- 滑动窗口(Sliding Window)------ 核心机制
这是流量控制的基础。接收方会在 TCP 头部的 窗口大小 字段中,告知发送方自己当前还能接收多少字节的数据(即接收缓冲区 RCV_WINDOW)。
原理:发送方只能发送接收方允许范围内的数据。
动态调整:随着接收方处理数据、缓冲区腾出空间,窗口大小会动态变大或变小。
零窗口:如果接收方缓冲区满了,窗口大小变为 0,发送方必须停止发送,直到窗口打开。
- 坚持计时器(Persist Timer)------ 解决死锁
当接收方发送了窗口更新(窗口打开),但这个确认报文不幸丢失了,会发生什么?
问题:接收方等待发送方发数据,发送方等待接收方的窗口更新,双方陷入死锁。
解决:发送方维护一个坚持计时器。当计时器超时,发送方会发送一个窗口探测报文段(Window Probe),询问接收方最新的窗口大小。
- 慢启动(Slow Start)与 拥塞控制(Congestion Control)------ 额外的网络环境适配
虽然这属于拥塞控制范畴,但它与流量控制紧密相关,共同决定了数据的发送速率。
慢启动:连接刚建立时,发送方发送速率(拥塞窗口 cwnd)从 1 开始,每经过一个 RTT(往返时延)就翻倍,快速探索网络带宽。
加法增大、乘法减小(AIMD):当网络出现拥塞(检测到丢包)时,将拥塞窗口减半;在未出现拥塞时,缓慢线性增加窗口大小,使发送速率平稳上升。
总结:TCP 流量控制主要依靠滑动窗口来实现收发双方的速度匹配,并通过坚持计时器防止死锁,辅以拥塞控制机制应对复杂的网络环境。
3.4 TCP的拥塞控制
3.4.1 拥塞控制的基本概念

3.4.2 拥塞控制的基本方法





3.4.3 TCP的四种拥塞控制方法

核心变量:
cwnd:拥塞窗口(发送方上限,防网络堵车)
rwnd:接收窗口(流量控制,防接收方崩)
最终发送上限 = \boldsymbol{\min(cwnd,\ rwnd)}
一、慢启动 Slow Start
连接初期,cwnd 从小到大慢慢试探网络
规则:每收到一个 ACK,cwnd + 1;每轮RTT,cwnd 翻倍
终止条件:
cwnd 增长到 慢启动阈值 ssthresh 时,退出慢启动,进入拥塞避免
二、 拥塞避免 Congestion Avoidance
到达 ssthresh 后开启
规则:每轮 RTT,cwnd 只+1(线性缓慢增长)
作用:平缓提速,避免快速打爆网络,减少拥塞
三、 快重传 Fast Retransmit
触发条件:
连续收到 3 个重复 ACK,判定报文段丢失(不等待超时计时器)
动作:
不等待超时,立刻重传丢失报文
更新阈值:ssthresh = \boldsymbol{cwnd / 2}
cwnd 重置为 ssthresh,直接进入快恢复
区别:
超时重传 = 严重拥塞;3个重复ACK = 轻度丢包
四、 快恢复 Fast Recovery
快重传后进入,不退回慢启动
cwnd 设为减半后的 ssthresh,线性缓慢增加
目的:网络只是轻微拥堵,不用大幅降速,快速恢复传输
极简流程总结:
-
初始:慢启动(指数暴涨)→ 到阈值
-
常态:拥塞避免(线性慢涨)
-
轻微丢包:快重传 + 快恢复(降窗、不崩盘)
-
严重超时:退回到慢启动重新试探
3.5 TCP拥塞控制与网际层拥塞控制的关系



3.6 TCP可靠传输的实现
TCP 实现可靠、无丢失、无重复、按序传输,依靠四大核心机制:
- 确认与超时重传(基础)
发送方发送报文后,开启超时计时器
接收方收到数据,返回ACK确认报文
超时没收到ACK → 判定丢包,自动重传
保证:数据不丢失
- 序列号(Seq)
TCP 每个报文段都带序列号
对每个字节数据编号
作用:
接收方按序号排序,解决乱序
剔除重复收到的报文
- 累计确认 + 重复ACK
接收方采用累计确认:只确认最后连续收到的字节
收到乱序/缺失报文,会发送重复ACK
配合快重传,快速修复丢包
- 滑动窗口机制
发送窗口、接收窗口配合
限制发送速率,配合流量控制+拥塞控制
避免缓冲区溢出、网络拥塞导致的数据丢失
3.7 TCP超时重传时间的选择
一、核心问题:
TCP 往返时间 RTT 是动态变化的,不能固定写死超时时间,否则:
时间太小:不必要重传,浪费资源
时间太大:丢包后等待过久,传输效率低
二、基础:加权平均 RTT(平滑往返时间)
采样RTT:每次测出一个实际往返时间 RTT样本
平滑RTT:
RTTs = (1-
)*RTTs +
*RTT样本
通常取 1/8
作用:平滑波动,反映长期稳定的RTT
三、引入偏差:RTT 偏差 RTTd
单纯平滑RTT忽略波动起伏,因此引入偏差:
RTTd = (1-
) * RTTd +
*|RTT样本 - RTTs|
通常取 1/4
四、最终超时重传时间 RTO(核心公式)
RTO = RTTs + 4 * RTTd
由 RFC2988 标准规定。
五、关键规则
- 超时重传后
一旦发生超时重传,下一次 RTO 直接翻倍,避免网络拥塞加剧。
- 只对首次报文测RTT
重传的报文不采样RTT,避免时间计算错乱。
3.8 TCP的选择确认
SACK 允许接收方在 ACK 中告知发送方已接收的非连续数据块,实现精确重传,避免不必要的重传与带宽浪费。
一、为什么需要 SACK?
传统 TCP 仅靠累积确认(ACK 号=期望收到的下一个字节序号),无法报告已收到的乱序/非连续数据。一旦中间丢包,发送方只能重传从丢失点开始的全部数据,效率极低。SACK 解决此问题,让发送方只重传真正丢失的段。
二、工作流程
握手协商:三次握手时,双方在 SYN/SYN-ACK 中携带 SACK-Permitted 选项(Kind=4),双方都支持才启用。
数据传输:发生乱序/丢包时,接收方在 ACK 中附加 SACK 选项(Kind=5),报告已接收的不连续块。
精确重传:发送方解析 SACK,只重传未被确认的丢失段,不重复发送已接收段。
三、报文格式(RFC 2018)
SACK-Permitted(协商用):Kind=4,Length=2,仅在 SYN/SYN-ACK 出现。
SACK(数据传输用):- Kind=5,Length≥2(每个块 8 字节:左边界+右边界)。
每个块用两个 32 位序号:Left Edge(起始序号)、Right Edge(结束序号+1)。
TCP 选项总长≤40 字节,最多容纳 4 个块(4×8=32 字节)。
四、关键机制与规则
与累积确认协同:ACK 号确认连续到该点的所有数据;SACK 补充报告后续已接收的非连续块。
与快重传配合:收到 3 个重复 ACK 触发快重传时,结合 SACK 可一次性重传多个丢失段,提升恢复效率。
不采样重传段 RTT:超时重传的段不用于 RTT 采样,避免 RTO 计算错乱。
发送方队列管理:未确认数据需保留;收到 SACK 后,标记对应块为已接收,仅重传未被 SACK 覆盖的段。
四、结语
本篇文章简单讲解了传输层的TCP和UDP两个重要的传输协议,这两个协议在日常生活中使用的频率是非常高的。