未出现的一般考点较少,这里的复习笔记一般可以满足考试需求 o.O
全部章节都有哦,具体看此博客
计算机网络-自顶向下期末复习一篇就够了------重点复习笔记整理-CSDN博客
3.1传输层服务
- TCP:可靠、有序传输
-
- 拥塞控制
- 流量控制
- 建立连接
- UDP:不可靠、无序传输
-
- 是"尽力而为"的 IP 服务的简单扩展
- 不提供的服务:
-
- 延迟保证
- 带宽保证
3.2多路复用和解复用
概念定义
- 复用(Multiplexing):在发送端将来自多个应用层的消息合并并通过单个传输层通道发送。
- 解复用(Demultiplexing):在接收端,将接收到的数据段分配给正确的套接字(socket)。
(复用是对通信信道的复用,而不是对传输数据报的分解。)
接收端的解复用过程:
- 主机接收 IP 数据报。
-
- 每个数据报包含源 IP 地址和目标 IP 地址。
- 每个数据报封装一个传输层段。
- ✨ 数据报datagram属于网络层,段segment属于传输层
- (数据报头含有IP地址,段头含有端口地址。)
- 每个段还包含源端口号和目标端口号。
- 主机根据 IP 地址和端口号将段转发给正确的套接字。
- TCP/UDP segment format
传输层协议的段格式(TCP/UDP)
每个传输层段头部会包含:
- 源端口号
- 目标端口号
这两个信息构成了解复用所需的关键字段。
🤞 P.S.TCP的面向连接 vs UDP的无连接
TCP(传输控制协议)是面向连接的 ,这意味着在数据传输之前,通信双方必须先建立一个逻辑上的连接 ,并在传输过程中维护状态信息。整个过程可以类比为打电话:
- 三次握手,四次挥手
- 可靠,有序,状态维护
UDP(用户数据报协议)是无连接的 ,这意味着通信前 不需要建立连接 ,数据直接发送,不管对方是否准备好接收。这个过程可以类比为寄信:
- 无握手,无状态维护,直接释放
- 不可靠,低延迟
无连接解复用(Connectionless Demultiplexing)------适用于 UDP
- 创建带有端口号的套接字。
- UDP 套接字的唯一标识为一个二元组:
-
- (目标 IP 地址,目标端口号)
- 当主机收到一个 UDP 段时:
-
- 检查段中的目标端口号
- 将该段交给该端口号对应的套接字
- 即使来自不同源 IP 和源端口的多个数据报,其目标端口相同,也会被送到同一个套接字。
示例场景:
多个客户端可能向这个端口发送数据,但都由同一个套接字接收。
面向连接的解复用(Connection-oriented Demux)------适用于 TCP
- TCP 套接字由一个四元组标识:
-
- 源 IP 地址
- 源端口号
- 目标 IP 地址
- 目标端口号
- 接收主机使用这四个字段来将段分配给正确的 TCP 套接字。
- 一个服务器可以同时支持多个 TCP 连接,每个连接由一个不同的四元组标识。
- 对于不持久连接的 HTTP 请求,每次请求都建立一个新的套接字连接。
3.3无连接传输UDP
UDP: 用户数据报协议 [RFC 768]
- UDP 是一种"无修饰"、"骨架式"的互联网传输协议。
- 提供"尽力而为(best effort)"服务,即:
-
- UDP 段可能会丢失。
- UDP 段可能无序地交付给应用程序。
- UDP 是无连接的:
-
- 发送方和接收方之间无需握手。
- 每个 UDP 段都是独立处理的,与其他段无关。
为什么需要 UDP?
- 无需连接建立:避免了握手带来的延迟。
- 结构简单:
-
- 发送端与接收端不需维护连接状态。
- 段头开销小。
- 无拥塞控制:UDP 可以按需快速传输数据,适用于实时性要求高的应用。
UDP segment结构(头部就是出去Application那四个)

- "长度":表示包括头部和数据在内的整个 UDP 段的字节长度。
- "校验和":用于差错检测。checksum
UDP 的常见用途
- 多媒体流式应用(如视频、语音):
-
- 容错能力强,对丢包不敏感;
- 对发送速率敏感。
- 其他应用:
-
- DNS(域名系统)
- SNMP(简单网络管理协议)
如何在应用层实现可靠性?
- 虽然 UDP 本身不提供可靠性,但应用可以在其之上实现:
-
- 添加应用特定的错误恢复机制,例如:
-
-
- 校验和校验;
- 重传机制;
- 序号追踪等。
-
3.4可靠性数据传输
概述
- 可靠数据传输(RDT,reliable data transfer)对于应用层、传输层和链路层都非常重要。
- 是网络中最核心的十大问题之一。
- 不可靠信道的特性决定了可靠数据传输协议的复杂程度。
可靠数据传输:起步
基本组件:
- 发送方(Send side):
-
rdt_send()
:由上层应用调用,将数据交由发送方RDT协议发送。udt_send()
:由发送方RDT协议调用,将数据段通过不可靠信道传输到接收方。
- 接收方(Receive side):
-
rdt_rcv()
:当数据段到达接收方时由接收方RDT协议调用。deliver_data()
:接收方RDT协议调用此函数,将数据交给接收方上层应用。

方框中的内容可理解为TCP缓冲区
开发思路:
- 我们将逐步开发可靠数据传输协议(rdt)的发送方与接收方。
- 本节仅考虑单向数据传输,但控制信息将在双向流动。
- 使用有限状态机(FSM)来描述协议的状态与行为:
-
- 每个状态由事件触发转换;
- 每次状态转换可以触发具体动作。
Rdt1.0:可靠信道上的可靠传输
- 假设底层信道完全可靠:
-
- 无比特错误;
- 无丢包。
- 发送方 FSM:
-
- 将数据打包成段,调用
udt_send()
发送。
- 将数据打包成段,调用
- 接收方 FSM:
-
- 通过
rdt_rcv()
接收段并调用deliver_data()
向上层交付数据。
- 通过
简单的数据流:
发送方 接收方
rdt_send(data) ─────► udt_send(packet)
rdt_rcv(packet)
extract(data)
deliver_data(data)
Rdt2.0:考虑比特错误的信道
新增问题:
- 信道可能导致比特翻转;
- 利用校验和检测错误。
如何处理错误?
- acknowledgements ACK(确认):接收方确认段无误;
- negative acknowledgements NAK(否认):接收方通知段存在错误;
- 发送方收到 NAK 后重传该段。
新机制(相较于 rdt1.0):
- 错误检测(如使用校验和);
- 接收方向发送方发送控制消息(ACK/NAK)。
rdt2.0:状态机描述(简化)
发送方 FSM:
- 等待来自上层应用的数据;
- 构建段(含校验和),发送;
- 等待 ACK 或 NAK;
-
- 若收到 ACK,继续;
- 若收到 NAK 或错误段,重发。
接收方 FSM:
- 检查接收到的段是否损坏;
- 若无误,提取数据,交付上层,并发送 ACK;
- 若出错,发送 NAK。

rdt2.0 的局限性
问题:
- 如果 ACK 或 NAK 本身被破坏 ,发送方将无法得知接收方状态。
错误恢复难点:
- 若重传,可能导致重复数据;
- 需要解决重复数据问题。
解决重复数据的方法
- 给每个段添加序列号;
- 接收方收到重复数据段时丢弃不交付;
- 协议变为"停等协议(Stop-and-Wait)":发送一个段后必须等待其确认。
Rdt2.1:处理错误确认的增强版
改进:
- 为每个段添加序列号(0 或 1);
- 接收方和发送方分别追踪当前预期的序列号;
- 能够识别 ACK 或 NAK 是否损坏或是重复。
状态数目增加:
- 每种状态必须记住当前段的序列号(0 或 1);
- 更复杂但能更好容错。
Rdt2.2:无 NAK 协议
- 功能与 rdt2.1 相同,但只使用 ACK:
-
- 接收方对每个正确接收的段发送 ACK(包括其序列号);
- 发送方收到重复 ACK 时,视为 NAK,重传当前段。
RDT2.1和2.2,正在等待的发送方只要收到与上一个ACK序号相反的ACK信号,就继续发送下一个。
Rdt3.0:考虑丢包的信道
新假设:
- 不仅存在比特错误,段也可能丢失(包括 ACK);
- 即使使用校验和、ACK、序列号,有时仍无法保证可靠性。
解决方法:
- 发送方设置计时器:
-
- 若超时仍未收到 ACK,则重传。
- 若 ACK 实际只是延迟而非丢失,重传段会被接收方识别为重复并丢弃(序列号机制仍有效)。
Rdt3.0 的操作与性能分析
工作流程:
- 发送方:
-
- 每发送一段就启动计时器;
- 若计时器到期未收到 ACK(可能因为丢包,也可能因为ACK丢失),则重发;
- 若收到 ACK,停止计时器。
性能问题:
- 示例:1 Gbps 链路,15 ms RTT,1KB 分组:
-
- 吞吐率约 33 KB/s,仅占链路带宽的一小部分;
- Stop-and-Wait 协议利用率极低。
流水线协议(Pipelined Protocols)C3P50
(相较于stop-and-wait)
概念:
- 发送方可以同时发送多个"飞行中"的未确认分组;
- 增大了序列号范围;
- 需要在发送方和接收方缓存未确认分组。
两种基本类型:
- 回退 N(Go-Back-N,GBN)
- 选择重传(Selective Repeat,SR)



3.5面向链接的传输TCP
TCP
- 全双工数据传输(Full duplex data):
-
- 数据可以在一个连接中双向同时传输。
- MSS(最大报文段长度):每个 TCP 报文段中允许的数据最大字节数。
- 面向连接(Connection-oriented):
-
- 发送方与接收方在发送数据前必须进行握手(即交换控制信息以初始化连接状态)。
- 流量控制(Flow controlled):
-
- 发送方不会发送超出接收方处理能力的数据。
- 点对点通信(Point-to-point):
-
- 每个 TCP 连接仅连接两个端点。
- 可靠、有序的字节流(Reliable, in-order byte stream):
-
- 数据流中没有明确的"报文边界"。
- 字节顺序交付给应用层。
- 流水线传输(Pipelined):
-
- 结合拥塞控制和流量控制设置窗口大小以进行高效数据传输。
- 发送与接收缓冲区:
-
- TCP 在两端都设置缓冲区用于临时保存数据。
TCP 报文段结构
|---------------------------------------------|-----------------|
| 字段 | 说明 |
| 源端口号、目标端口号 | 用于标识通信的进程 |
| 序列号(Sequence Number) | 表示该段数据的第一个字节编号 |
| 确认号(Acknowledgment Number) | 表示期望收到的下一个字节编号 |
| 头部长度、保留位、控制位(如URG, ACK, PSH, RST, SYN, FIN) | 控制连接建立、断开、数据推送等 |
| 接收窗口大小(Receive Window) | 表示接收方可接受的字节数 |
| 校验和 | 检测段在传输过程中是否出错 |
| 紧急指针、选项字段(可变) | 特殊数据控制 |
TCP segment 结构


TCP 序列号与确认机制
- 序列号sequence number:每个报文段携带的数据第一个字节的编号。
- 确认号acknowledgement number:期望接收的下一个字节编号。
-
- 累计确认( Cumulative ACK ):确认号表示之前所有字节都已成功接收。
例如:一个 500,000 字节的文件,用 1000 字节作为 MSS,TCP 会创建 500 个段。
- 第一段的序列号为 0;
- 第二段为 1000;
- 第三段为 2000,以此类推。

在A发送给B的TCP segment中:
Seq. #'s = n:表示这次A发送给B的数据是从第n字节开始的。
ACKs = m:表示A收到的B发送给A的数据 中,前m-1个字节都已确认无误收到**(累计确认)**,期望收到B发给A的从m字节开始的数据。
体现了全双工特性。
TCP 往返时间Round Trip Time(RTT)与超时(Timeout)
设置超时的挑战:
- RTT 会变化,因此:
-
- 过短 → 会导致不必要重传;
- 过长 → 会导致响应变慢。
解决方法:
-
测量 SampleRTT:从发送段到收到 ACK 的时间。
-
使用 加权移动平均 计算 EstimatedRTT:
EstimatedRTT = (1 - α) × EstimatedRTT + α × SampleRTT
-
(α 通常为 0.125,参考 RFC 2988)
-
设置 超时间隔(TimeoutInterval):
-
DevRTT:Round Trip Time Deviation
-
用于估计往返时间变化幅度,DevRTT 是 RTT 偏离平均值的"平均偏差",越大说明网络越不稳定。
Deviation:离差
DevRTT = (1 - β) × DevRTT + β × |SampleRTT - EstimatedRTT|
TimeoutInterval = EstimatedRTT + 4 × DevRTT
- (β 通常为 0.25)
TCP 实现可靠数据传输
- TCP 在不可靠的 IP 之上实现可靠服务。
- 支持流水线传输 和累计确认。
- 触发重传的条件包括:
-
- 超时事件;
- 收到重复的 ACK。
TCP 发送端事件处理(简化版)
- 应用数据到达时:
-
- 创建报文段并设置序列号;
- 若计时器未运行,启动计时器(用于追踪最早未被确认的段 );
- 更新下一个序列号指针。
- 设置超时间隔为:TimeOutInterval(超时重传时间)。
- 计时器超时时:
-
- 重传最早的未确认段;
- 重新启动计时器。
- 接收到 ACK 时:
-
- 若 ACK 覆盖了新的未确认数据,更新确认边界;
- 若仍有未确认数据,则保持计时器运行。
TCP 重传场景分析
场景 1:提前超时
- 数据实际上已送达但 ACK 未及时到达 → 触发不必要的重传。
场景 2:ACK 丢失
- 发送方未收到 ACK → 触发重传,接收方忽略重复数据(通过序列号识别)。
场景 3:快速重传Fast Retransmit
- 如果发送方连续收到 3 个相同的 ACK(即重复 ACK),则假定丢包,提前重传,无需等待超时。
快速重传Fast Retransmit
前提:
- 只有当接收方收到一个合法的数据段时(哪怕乱序),才会发送ACK。 如果接收方什么都没有收到,则不会回复ACK。即:没有ACK的定时重传!!
- 延迟 ACK(Delayed ACK)机制:
- RFC1122 规定:如果接收方收到按序数据段 ,可以延迟 ACK 最多 500ms,看是否还能马上收到下一个段(为了合并 ACK);
- 但如果没有后续数据到达 ,接收方仍会在500ms 内发送 ACK;
快速重传机制
-
实质:发送方在收到三次重复的ACK信号时,则认为最后一次ACK后的段丢失,于是在计时器结束之前重发段。
event: ACK received, with ACK field value of y
if (y > SendBase) {
// 收到新的 ACK,说明有新段被确认
SendBase = y
if (有未被确认的段)
启动定时器
}
else {
// 收到重复 ACK(y == SendBase)
增加该 ACK 的重复次数计数器
if (该 ACK 重复次数 == 3)
立即重传该序号的数据段(快速重传!)
}

-
TCP 发送方发送多个段(segments)时,可能是连续的,如:
1000-1049,1050-1099,1100-1149,...
-
如果其中某一个段丢失,比如 1050-1099 段丢了;
-
接收方收到 1000-1049 后,再收到 1100-1149;
-
接收方无法按序交付,于是就不断重复发送:
ACK=1050,ACK=1050,ACK=1050...
-
因为接收方"仍然等待字节 1050"。
TCP 利用这种现象:连续收到三个相同 ACK(比如 ACK=1050),发送方就假设字节 1050 的段丢失了,立刻重传,而不等超时。
TCP ACK 生成策略(RFC 1122, 2581)
|----------------|--------------------------------------|
| 接收事件 | 响应策略 |
| 收到预期序列的段 | 延迟 ACK,等待最多 500ms 看是否有下一个段(为了合并 ACK) |
| 收到连续两个段 | 立即发送 ACK |
| 收到高于期望序列的段(乱序) | 立即发送重复 ACK,指出期望字节编号 |
| 收到填补乱序空缺的段 | 立即发送 ACK |
发送方:通过**流水线协议Pipelined Protocols(更细致的,利用了滑动窗口机制Sliding Window)**可能会连续发送很多连续的段,并不是Stop-And-Wait,在收到ACK之后才发送下一个段。
- PS:TCP 是滑动窗口协议(带重传机制)的典型流水线协议,实现高吞吐。
接收方:只有在收到有效的段(不管是否乱序)后才会发送ACK,且此ACK为"期望的下一字节",即last ACKed数据的下一个seq.#,告诉发送方,"你应该给我发送的是这一段。"
- PS: TCP 使用"累计确认"(cumulative ACK),始终 ACK 最小的、尚未收到的字节编号。
- ACK 的作用不是"告诉发送方我收到了什么",而是"告诉你我还需要哪个字节"。
TCP 流量控制TCP Flow control

- 接收方设置接收缓冲区;
- 接收方会告知发送方其缓冲区剩余空间(RcvWindow);
- 发送方限制未确认的数据量不超过接收方 RcvWindow;
- 保证不会导致缓冲区溢出;
- 提供速率匹配机制:发送速率与接收进程读取速率相匹配。
三、公式含义(左下角)
RcvWindow = RcvBuffer - (LastByteRcvd - LastByteRead)
各变量含义如下:
|-----------------------------|-----------------------|
| 名称 | 含义 |
| LastByteRcvd | TCP 接收方已经收到的最后一个字节序号 |
| LastByteRead | 应用程序已经从缓冲区读取的最后一个字节序号 |
| LastByteRcvd - LastByteRead | 表示缓冲区中"未被应用消费的字节数" |
| RcvBuffer | 接收缓冲区总容量 |
| RcvWindow | 当前剩余空间(spare room) |
✅ 本质上就是:接收窗口 = 总容量 - 当前正在占用的空间
四、工作机制逻辑
- 接收方接收到数据 → 放入缓冲区;
- 每次发送 ACK 时,把
RcvWindow
值带上; - 发送方根据 RcvWindow 控制发送节奏(限制未确认数据的量);
- 若 RcvWindow = 0 → 发送方停止发送;
- 当接收方的应用程序读取数据后 → 空间释放 → RcvWindow 增大 → 发送方继续发送。
TCP连接管理TCP Connection Management
TCP连接建立
请记住:TCP 的发送方与接收方在传输任何数据段之前,必须先"建立连接"。
连接建立过程包括:
- 初始化 TCP 状态变量:
-
- 序列号(Sequence numbers)
- 缓冲区、流量控制信息(如 RcvWindow)
👤 客户端(连接发起方):
Socket clientSocket = new Socket("hostname", "port number");
🖥️ 服务器端(等待被连接):
Socket connectionSocket = welcomeSocket.accept();
三次握手(Three-way handshake):
详见图 3.39(第290页),流程如下:
重要信息:SYN段(Synchronize,同步段)
✅ 第一步:
客户端向服务器发送 TCPSYN(Synchronize,同步) 段:
- 声明客户端的初始序列号(initial sequence number);
- 此时无数据,只有控制信息。
✅ 第二步:
服务器收到 SYN 后,回复一个 SYNACK 段:
- 分配接收缓冲区;
- 包含服务器自己的初始序列号ISN(Initial Sequence Number);
- 作为对 SYN 的确认。
✅ 第三步:
客户端收到 SYNACK 后,回复一个 ACK 段:
- 可包含实际应用数据;
- 至此连接正式建立,双方可以开始传输数据。

✅ 第一步:客户端发送 SYN(连接请求)
SYN = 1, seq = client_isn
- SYN=1:表示这是一个连接请求段;
- seq=client_isn:客户端选择的初始序列号(Initial Sequence Number);
- 此时段中没有实际数据,但携带了控制信息;
- 目的:告诉服务器:我想建立连接,而且我从哪个字节号开始计数。
✅ 第二步:服务器回应 SYN+ACK(连接同意 + 确认)
SYN = 1, seq = server_isn, ack = client_isn + 1
- SYN=1:服务器也声明它自己的初始序列号;
- seq=server_isn:服务器的初始序列号;
- ack=client_isn+1:表示确认客户端的初始序列号;
- SYN+ACK:这是一个组合段,表示"我同意建立连接,并确认你的请求"。
✅ 第三步:客户端发出 ACK(确认服务器回应)
SYN = 0, seq = client_isn + 1, ack = server_isn + 1
- SYN=0:说明这是一个普通的数据确认段;
- seq=client_isn+1:客户端此时的数据序列号已经准备好;
- ack=server_isn+1:确认服务器的初始序列号;
- 至此,三次握手完成,连接建立。
|-----------------------------|--------------------|
| 段字段 | 含义 |
| SYN=1 | 表示是连接请求或响应 |
| ACK=x | 表示确认收到了编号为 x-1 的数据 |
| seq=y | 表示我从编号 y 开始发我的数据 |
| client_isn / server_isn | 各自初始化时随机生成的序列号 |
连接关闭 - 四次挥手
TCP连接的关闭:
例如,客户端关闭连接:
clientSocket.close();
✅ 第一步:
客户端的终端系统发送一个 TCP FIN 控制段 给服务器,表示"我没有数据可发了"。
✅ 第二步:
服务器收到 FIN 后,回复 ACK,并开始关闭连接:
- 此时服务器可能还有数据未发完,或也准备关闭;
- 它会随后发送一个 自己的 FIN 段。
✅ 第三步:
客户端收到服务器的 FIN 后,回复 ACK,进入"时间等待"状态(TIME_WAIT):
- TIME_WAIT 会持续一段时间,以便:
-
- 如果服务器没有收到 ACK,会重发 FIN;
- 客户端仍在监听并确认。
✅ 第四步:
服务器收到 ACK 后,连接关闭(CLOSED)。
🔁 注意:如果两边同时发送 FIN,也可以通过轻微修改该过程处理。

3.6TCP 拥塞控制
概览
拥塞窗口(cwnd)的含义
发送窗口 = Min {拥塞窗口(cwnd),接收窗口}
TCP 发送方感知拥塞的两个事件
TCP 慢启动
相关概念:慢启动、拥塞避免、快速恢复、阈值、带宽探测、加法增加(拥塞避免状态)、乘性减(三个重复 ACK)
- CongWin 即 拥塞窗口(Congestion Window) 的缩写,通常用 cwnd 表示。
-
- 作用:动态调整发送方的发送速率,避免网络过载。
- Threshold 即 阈值(ssthresh) ,全称为 慢启动阈值(Slow Start Threshold)
什么是拥塞
- 非正式定义:过多的数据源以过快的速度发送数据,导致网络无法处理。
- 拥塞 ≠ 流量控制(Congestion ≠ flow control):
-
- 流量控制是端到端的速率匹配;
- 拥塞控制 是全网络层面的资源协调问题。
- 拥塞的表现形式包括:
-
- 丢包(由于路由器缓存溢出);
- 高延迟(由于路由器排队缓慢);
- 拥塞控制是网络设计中的十大核心问题之一
注意TCP提供的是端到端的拥塞控制,发送端根据自身观察判断网络是否拥塞
TCP 拥塞控制
拥塞控制的基本策略
Congestion Window
- **控制方为发送方:**发送方动态调整
- 属于流量控制 Flow Control
Receive Window
- **控制方为接收方:**接收方Receive Buffer的一部分
- RcvWindow = RcvBuffer - (LastByteRcvd - LastByteRead)
- 属于拥塞控制 Congestion Control
TCP 发送方通过控制拥塞窗口(Congestion Window, 简称 CongWin)的大小,限制其发送速率:
已发送未确认的数据量 ≈ LastByteSent - LastByteAcked ≤ CongWin
拥塞窗口的性质:
- 是一个动态调整的变量;
- 表示发送方当前估计的"可用带宽";
- 随网络拥塞状况而变化。
拥塞的感知方式:
- TCP 通过以下两种事件判断可能的拥塞:
-
- 超时(Timeout);
- 三次重复确认(Triple Duplicate ACKs)。
TCP 拥塞控制的三大机制
- AIMD(加性增大,乘性减小);
- 慢启动(Slow Start);
- 超时后的保守处理(Conservative after Timeout)。
- AIMD:加性增大,乘性减小
additive increase, multiplicative decrease
- 加性增大(Additive Increase):
-
- 每个往返时延 RTT 内将拥塞窗口增加一个 MSS(最大报文段大小)。就是再Conwin>threshold的时候,一个RTT增加一个Conwin的意思差不多
- 乘性减小(Multiplicative Decrease):
-
- 一旦检测到拥塞(例如丢包),将 CongWin 减半或者直接设置为1。
整体效果是"锯齿形"增长,探测带宽直到丢包发生。
- 慢启动(Slow Start)
目的:
- 防止新连接一开始就占用过多网络资源。
原理:
- 初始化时设置
CongWin = 1 MSS
; - 每收到一个 ACK,CongWin 增加 1 MSS;
- 即:每个 RTT 使窗口 指数增长。
举例:若 MSS = 500 字节,RTT = 200ms,则初始速率为 20kbps,但指数增长很快提升。

- 区分不同的丢包类型
- 三次重复 ACK(3 dup ACKs):
-
- 说明网络仍能传送部分段;
- 响应较"温和" → 将 CongWin 减半,并线性增长。
- 超时事件(Timeout):
-
- 说明网络可能严重拥塞;
- 更"激进" → 将 CongWin 设置为 1 MSS,重新进入慢启动。
拥塞控制中阈值的引入(Threshold)
- 当丢包发生:
-
Threshold = CongWin / 2
;- 不同事件触发不同策略:
|----------|-----------------------------------------|
| 事件 | 动作 |
| 三次重复 ACK | CongWin ← Threshold,进入线性增长阶段 |
| 超时 | CongWin ← 1 MSS,Threshold ← CongWin / 2 |

- 当拥塞窗口 CongWin 达到"阈值 Threshold"时,就从"指数增长"切换为"线性增长"。
- 慢启动(Slow Start)指数增长
- 到达Threshold 切换点。
- 拥塞避免(Congestion Avoidance):线性增长。
- 当发生丢包(loss event)时:
- 将 Threshold 设置为当前 CongWin 的一半;
- CongWin 回退为 1 MSS(或新的起始值)重新开始慢启动。
TCP Tahoe检测到拥塞:
Threshold 设为一半, CongWin 重置为1,再次慢启动(从1开始重新指数增长)。
- 没有快速恢复,每次丢包都归零,非常保守。
TCP Reno检测到拥塞:
Threshold 设为一半, CongWin不是重置为1,而是快速恢复(Fast Recovery)到新的Threshold。
- 直接从 Threshold 开始线性增长,更加高效。
TCP 拥塞控制总结
- CongWin < Threshold :处于慢启动阶段 → 指数增长;
- CongWin ≥ Threshold :进入拥塞避免阶段 → 线性增长;
- 发生三次重复 ACK :设置
Threshold = CongWin / 2
,将 CongWin 重置为 Threshold; - 发生超时 :设置
Threshold = CongWin / 2
,CongWin 重置为 1 MSS。