
(以下内容全部出自上述课程)
目录
- 可靠传输&流量控制
-
- [1. 确认号、接收窗口大小](#1. 确认号、接收窗口大小)
- [2. TCP传输的底层原理](#2. TCP传输的底层原理)
- [3. 累积确认](#3. 累积确认)
- [4. 捎带确认](#4. 捎带确认)
- [5. 超时重传机制](#5. 超时重传机制)
- [6. 快重传机制、立即确认机制](#6. 快重传机制、立即确认机制)
- [7. 小结](#7. 小结)
- 拥塞控制
-
- [1. 慢开始、拥塞避免](#1. 慢开始、拥塞避免)
-
- [1.1 专有名词](#1.1 专有名词)
- [1.2 考题特点](#1.2 考题特点)
- [1.3 过程分析](#1.3 过程分析)
- [2. 快重传、快恢复](#2. 快重传、快恢复)
可靠传输&流量控制

回顾可见:TCP报文段

1. 确认号、接收窗口大小
大前提:
- 发送和接收是一个来回,发送的seq和接收的ack是相互关联的(自己的ack是接收的对面数据的seq)。
- rwnd:指的是自己的接收缓冲区,每次发送过去的都是自己接收缓冲区(剩余)的大小。
- 发送窗口 是根据接收方 的接收缓冲区来变化的
复习:
-
序号seq :用于标记数据部分第一个字节在原始字节流中的位置,发送方自己设置
握手1、握手2不能携带数据,但是要消耗一个序号
握手3如果不携带数据就不消耗序号
-
握手1&握手2:发送和接收的初始seq号可以不同(发送是发送的,接收是接收的)
-
握手2:接收方被问了才会告诉自己的rwnd大小
-
握手3:发送方告知对方自己的rwnd大小
-
服务器收到3个字节数据 :看下一张底层原理的图

服务器收到3个字节数据:
-
seq=600:第一次发送信息,初始序号从600开始
-
ack=200:服务器一直没给客户发送信息,所以一直是初始序号
-
rwnd=10:发送方自己的接收缓冲池是10B
服务器返回最新确认号、最新接收窗口大小:
-
seq=200:服务器一直没给客户发信息,所以一直是初始序号
-
ack=603:发送的初始序号是600,+3B就是截止到603都收到了
-
rwnd=5:握手2的时候说过服务器自己窗口是8,现在接收了3B,-3B就是还剩5B的位置
-
发送窗口=5:因为上一个阶段发送了3B,接收缓冲区只有5B的位置,所以发送缓冲区最多也只能一次性发5B的数据
-
10B发送缓冲区:发送方这边先把这个给装满,但是只先发送了3B,发送完了的数据就踢出去,继续往里面装入数据
-
接收缓冲区8B:收到了发送过来的3B
ps:其余不懂得名词可见下方的TCP传输的底层原理(就是下一小节)

2. TCP传输的底层原理
每个阶段的底层原理都会按照侧重点进行对比理解,所以这里只是放一下总体图:
- 电脑:客户端,就是你自己、IP(你的收货地址)
- 服务器:就是你用的软件的服务器,需要响应你的对象(给你发货的商家)、IP(商家的发货地址)
- 应用层:两边的端口号(快递地址)、带起始序号的待发送数据(快递=数组)、即将接收的数据的预留位置(空地儿=空数组)
- 传输层:Socket套接字(信息整合=快递单)
- 发送缓冲区:以少的一方为主(一个8一个10那就是8),满了才发过去(装一车货才会去送快递,要不然来来回回跑)
- 接收缓冲区:以少的一方为主,满了或者连续就可以送给应用层(你收快递,有一点儿收一点儿,不一定一个时间到)
- 窗口 :就是能装入字节更少的一方缓冲区的大小,比如图中最少的是8B<10B,那实际上的窗口就都是8B
(虽然发送方说自己是10B,但是接收方是8B,所以它最多也只能一起发送8B大小的数据)

我们有微信,发送消息需要传到微信服务器上,别人也有微信,他们发送消息也需要传到微信服务器上,
微信服务器只有一个绑定端口号,所以一个端口可以建立多个TCP连接,可以给我发送消息,也可以给你发送消息。

3. 累积确认
- 累积确认 :收到多个连续报文段,只返回一个ACK

服务器连续收到两个报文段: - seq=603&seq=605:发送方连续发送了两个2B的数据
- 对应图中就是3&4、5&6:可能5&6先到达,但是因为seq=605,所以也可以很正确地找到自己的位置,将还未到达的数据空出来
- ack=200:服务器一直没给客户发送信息,所以一直是初始序号
- rwnd=10 :客户一直没接收信息,所以接收缓冲区一直是空的(10B)

累积确认: - seq=200:服务器一直没给客户发信息,所以一直是初始序号
- ack=607:第一次3B+二三次2B*2=7B,+初始序号600,刚好是截止607之前的数据都收到了
- rwnd=1:接收缓冲区8B-已经接收数据7B=1B剩余空间
- 发送窗口=1 :根据对方接收缓冲区进行调整

又接收1B数据后,服务器的接收缓冲区满了,就需要交给应用层,存进空数组里(把快递放进自己预留的位置上)
所以此时的接收缓冲区又变回原来的8B了
发送方的发送窗口根据对方的接收缓冲区变化,也变回8B了

4. 捎带确认
捎带确认 :服务器刚好有数据要发送,就连带着确认刚接收的数据,顺便儿把自己要发送的数据也带上
简单记 :确认+数据,一起打包发送

服务器收到2B,可以先不交付给应用层:
- seq=608:现在为止,发送序号为608的数据
- ack=200:服务器一直没给客户发送信息,所以一直维持初始序号
- rwnd=10:因为没有接收的数据,所欲客户的接收缓冲区一直是10B
捎带确认:
-
seq=200:服务器从序号为200的数据,开始给客户发送数据
-
ack=610:表示对方发送的数据截止610号全部正确接收
-
rwnd=6:接收缓冲区8B-刚接收的数据2B=还剩的空间6B
-
数据5B:服务器把自己要发送的数据装入自己的发送缓冲区
-
发送窗口=8 :服务器的发送缓冲区一共就8B

客户捎带确认6B数据:
-
seq=610:从序号610继续给服务器发送数据
-
ack=205:表示服务器给自己发送的数据截止205号全部正确接收
-
rwnd=5:自己的10B接收缓冲区-接收服务器的数据5B=还剩空间5B
-
数据6B:自己不但确认了,还要再发送6B数据过去
-
发送窗口=6 :服务器接收缓冲区只有6B大小了,虽多一次发送6B数据

上述客户又给服务器发送了6B数据,刚好把服务器的接收缓冲区装满,直接发配应用层
缓冲区未满也可以按序交付给应用层:
图中可见从0~15都交付给应用层了,如果传来的按照顺序刚好是16、17,也可以直接交付给应用层
但如果是17、18,缺了个16就不是按照顺序了,所以就不可以直接交付应用层

5. 超时重传机制
每发出一个报文段,就会设置一个超时重传计时器
在计时器的时间内,如果一直每接收到对方发来的ack确认,发送方就会重传报文段,然后重置计时器

就算是接收方确实接收到了报文段,但是自己的ack段丢失了
发送方接收不到确认信息也会重传报文段
总之:怎样都不会漏报文段

6. 快重传机制、立即确认机制

ps:下图正确
一般情况下:
- 我们连续发送了4个报文段,但是只有第二个报文段没有被接收到
- ack只会返回截止多少号之前的数据都接收到了
- 所以就只会回复第二个报文段之前的报文段接收到了,发送方就会重传后三个报文段
- 问题来了:我们后两个报文段已经收到了,但是它还是给我们发送了三个,就很浪费时间
所以!我们引入了快重传机制,搭配立即确认机制使用(一对连体婴)
- 我们只需要在接收到一个报文段之后,立即返回确认信息
- 这样如果只有第二个报文段没被接收到,就只有第二个报文段没有确认信息
- 发送方就知道只有这一个没被接收到,所以就只会重发第二个报文段
考点:
- 如果发送方收到三个确认号相同的冗余ACK,就立即重发对应的报文段
- 第一个ACK不属于冗余ACK,后面的才是冗余的ACK
- 简单记:发现连续四个确认号相同的ACK ,就立即重传

在第四个确认号相同的时刻立即重传:t3

7. 小结


拥塞控制

- 慢开始:严重拥塞
- 快重传:有点儿拥塞

1. 慢开始、拥塞避免
1.1 专有名词
-
cwnd (Congestion Window,拥塞窗口)
中文名 :拥塞窗口
含义 :TCP 发送方允许发送但还未被确认的数据量(以字节为单位)
通俗理解 :相当于你手里能同时拿着多少个快递去投递。cwnd 越大 → 可以发更多数据(效率高)
cwnd 越小 → 发得少(防止网络拥堵)
-
ssthresh (Slow Start Threshold,慢开始门限)
中文名 :慢开始门限 / 拥塞控制阈值
含义 :一个"警戒线",决定使用哪种算法增长 cwnd
作用 :当 cwnd < ssthresh → 使用 慢开始算法(指数增长)
当 cwnd >= ssthresh → 使用 拥塞避免算法(线性增长)
-
慢开始 (Slow Start)
核心规则 :每次收到一个 ACK,就让 cwnd 翻倍
特点 :指数级增长第 1 轮:cwnd = 1
第 2 轮:cwnd = 2
第 3 轮:cwnd = 4
第 4 轮:cwnd = 8
......直到达到 ssthresh
-
拥塞避免 (Congestion Avoidance)
核心规则 :在一个 RTT 内,即使收到多个 ACK,也只让 cwnd += 1
特点 :线性增长(缓慢爬升)每过一个 RTT(往返时间),cwnd 增加 1
不再是指数增长,而是"稳扎稳打"
-
RTT (Round-Trip Time,往返时间)
含义 :发送一个包,收到对应 ACK 所需的时间
通俗理解 :你把快递寄出去,等对方签收后给你回信的时间
在图中的体现:横轴上的"传输轮次"就是按 RTT 分段的 -
网络拥塞 (Network Congestion)
含义 :网络中的路由器或链路负载过高,导致丢包、延迟增加
触发条件:当 TCP 收到 三个重复的 ACK 或 超时重传 时,认为发生了拥塞 -
乘法减小 (Multiplicative Decrease)
含义:当检测到拥塞时,将 ssthresh 和 cwnd 都减半 -
加法增大 (Additive Increase)
含义 :在拥塞避免阶段,每经过一个 RTT,cwnd += 1
特点 :缓慢提升吞吐量,避免再次引发拥塞

1.2 考题特点
发送窗口的上限=接收窗口和拥塞窗口中更小的一个

1.3 过程分析
最开始:cwnd翻倍地增长:1-->2-->4-->8-->16

16达到ssthresh,就必须变成一轮只能+1:16-->17-->18-->...-->24

24达到网络拥塞(超时重传的情况),直接把cwnd恢复为1,且ssthreah=cwnd/2=24/2=12

超时重传,一夜回到解放前且门槛更严格:1-->2-->4-->8-->12(到达ssthresh,被制裁了)

到达ssthresh:12-->13-->14-->...-->21



2. 快重传、快恢复
-
拥塞避免 (Congestion Avoidance)
核心规则 :在一个 RTT 内,即使收到多个 ACK,也只让 cwnd += 1
特点 :线性增长(缓慢爬升)每过一个 RTT(往返时间),cwnd 增加 1
不再是指数增长,而是"稳扎稳打"
-
快重传:连续收到4个确认号相同的报文段,立即重传
-
快恢复算法 :ssthresh=cwnd=cwnd/2,然后改为+1

3个冗余:24-->12-->13-->14-->...
注意:ssthresh不能小于2
