前言
目前正在备考 24 考研,现将 24 计算机王道的 408 学习整理的知识点进行汇总整理。
博主博客文章目录索引:博客目录索引 (持续更新)

一、传输层提供的服务
1.1、传输层的功能
传输层只有主机才有的层次。

传输层的功能:
1、传输层提供进行和进程之间的逻辑通信。
- 逻辑通信:表面上是连个主机的进程之间进行通信,实际在通信的时候会首先发送方会从最上层一步步封装到物理层,将比特流放入到链路中传输,接着中间经历多个中间系统,最终到达主机再一步步解封装,最终指定的应用请求得到数据。

- 对于网络层提供主机之间的逻辑通信。
2、复用与分用。
- 例如:微信与 QQ 发送的数据最终都会使用同一个传输层的协议进行传输(复用),最终目标方手机同时会在传输层将数据报进行拆分来进行分用传给到不同的应用当中(分用)。
3、传输层对收到的报文进行差错检测。
- 在网络层阶段包含一个首部校验,这个是用来校验 IP 数据报的首部的,没有检错的功能原因是因为其上层传输层中会对传输层报文段进行差错检测。对于传输层 + 网络层可以实现一个可靠传输的功能。
- 传输层中并不一定能够一个可靠传输,因为包含有一个 UDP 和 TCP,其中 TCP 是保证可靠传输的。
1.2、传输层的两个协议(TCP、UDP)
两个协议为:TCP、UDP。前者可靠,后者不可靠。
TCP 与 UDP 协议的对比:
①TCP:面向连接的传输控制协议。
- 传输数据过程:传输数据之前必须建立连接,数据传送结束后要释放连接。不提供广播或多播服务。
- 由于 TCP 要提供可靠的面向连接的传输服务,因此不可避免增加了许多开销:确认、流量控制、计时器及连接管理等。
- 是否可靠:可靠,面相连接,时延大。
- 应用场景:适用于大文件。
②UDP:无连接的用户数据报协议 UDP。
- 传输数据过程:传输数据之前不需要建立连接,收到 UDP 报文后也不需要给出任何确认。
- 是否可靠:不可靠,无连接,时延小。
- 应用场景:适用于小文件。
1.3、传输层的寻址与端口(常见端口介绍)
复用与分用:
复用:应用层所有的应用进程都可以通过传输层再传输到网络层。分用:传输层从网络层收到数据后交付指明的应用进程。
端口:传输层的 SAP,用来标识主机中的应用进程,一个应用进程运行都会有端口号。
- 主要分为:逻辑端口 / 软件端口,指的是应用进程的端口。对于硬件端口则指的是真实物理世界中主板上的一些接口。
- 端口关系:端口号只有本地意义,在因特网当中不同计算机的相同端口是没有联系的。
- 端口号长度:为 16bit,可以表示 65536 个不同的端口。
端口号按照范围分:包含有服务端的端口号、客户端使用的端口号

其中一些常见的固定应用服务的使用端口如下:

在网络中采用发送方和接收方的套接字组合来识别端点。
套接字:唯一标识了网络中的一个主机和它上面的一个进程。
套接字Socket = (主机IP地址,端口号),其中主机 IP 地址能够去标识定位一个网络中的主机,而对于端口号则是用来表示主机上的某个进程。
二、UDP 协议
2.1、认识 UDP 功能和特点
UDP 功能:只在 IP 数据报服务之上提供了很少的功能,如复用分用和差错检测功能。
UDP 的主要特点:
1、UDP 是无连接的,减少开销和发送数据之前的时延。
2、UDP 使用最大努力交付,即不保证可靠交付。
- 若是 UDP 协议不能够保证可靠交付,那么可靠交付就交由传输层的上一层应用层来保证可靠以及顺序的交付。
3、UDP 是面向报文的,适合一次性传输少量数据的网络应用。
应用层给 UDP 多长的报文,UDP 也会照常发送,即一次发一个完整报文,由于也是不可靠的交付,容易导致数据丢失,若是传输的数据量不大,这样即使发生丢失的的情况损失也比较小。

- 若是数据太大,那么在网络层就需要分片,因为对于接下来传递给链路层,在链路层中有一个 MTU 的要求。
- 若是数据太小,小到比首部还少,那么就会降低网络层的效率,希望的是一个数据报当中数据信息尽可能多,首部附加信息尽可能少。
4、UDP 无拥塞控制,适合很多实时应用。
- ** 并不是说没有拥塞控制,那么网络即使再拥塞,UDP 也不会让发送方的速度放缓一些,此时就不会控制这个问题。对于这种情况是否会觉得这个协议不好?** 实际上不是,正因为 UDP 没有拥塞控制,也带来了一些优点,如适合很多实时性的应用,如 IP 电话、视频会议,并且是允许在网络出现拥塞的情况下,丢弃一些数据的,因为这些实时性的应用,不能允许数据有太大的延迟,实际上丢一点也是允许的。
- 对于拥塞情况特别严重,也会有一定的补救措施,例如向前纠错或者重传已经丢失的报文。
5、UDP 首部开销小,8B,TCP 为 20B。
2.2、UDP 首部格式
首部字段总和固定是 8B,其中包含源端口号、目的端口号、UDP长度、UDP检验和都是 2B(16 位)。

16位UDP长度:指的是数据字段 + 首部字段,若是数据字段为 7B,那么这个 UDP 长度就是 15。
16位UDP检验和
- 情况 1:检测整个 UDP 数据报是否有错,错就丢弃。
- 情况 2:分用时(接收端接收到时需要进行分用给不同进程根据端口号),若是找不到对应的目的端口号,那么此时就会丢弃报文,并给发送方发送 ICMP “端口不可达” 的差错报文。
2.3、UDP 伪首部字段分析
伪首部只有在计算校验和的时候才出现,不向下传送也不向上递交。伪首部就是模仿的 IP 数据报的首部。

源IP地址:4 个字节。目的IP地址:4 个字节。0:1 个字节,全 0 也就是为首部的第三个字段固定全 0。- 在伪首部中的
17:1 个字节,封装 UDP 报文的 IP 数据报首部协议字段是 17。 UDP长度:2 个字节,UDP长度 = UDP首部8B + 数据部分长度(不包括伪首部)
2.4、伪首部校验 UDP 用户数据报过程
如何使用伪首部来校验 UDP 用户数据报有没有发生差错?
将它看成有许多 16 位的字串连接起来的,也就是很多个 4 个字节的组成部分,如下图中的右半部分,每 16 位作为一组并排写:

在发送端:
1、填上伪首部。
2、全 0 填充检验和字段。
3、全 0 填充数据部分(UDP 数据报要看成许多 4B 的字串接起来)。
4、计算:将伪首部 + 首部 + 数据部分采用二进制反码求和。
5、将求和反码填入到首部的检验和字段。
6、去掉伪首部,发送。
在接收端:
1、填上伪首部。
2、伪首部 + 首部 + 数据部分采用二进制反码求和。
- 注意:在发送端中的检验和计算求和时是全 0,而在接收端的时候此时检验和是之前的求和结果取反,我们这边是加上的检验和。
3、最终得到结果全为 1 则无差错,否则丢弃数据报 或 应用层 附上出差错的警告。
如下在求和中有区别的就是检验和部分,在接收端时这个检验和为发送端时候的一个检验和,不再是使用全 0 来计算:

** 为什么最终和为 1?** 可以看到在发送端时最终的结果取得是反码放入到检验端,那么将计算得到的值 + 反码值,那就是全 1,如下两行相加。

三、TCP 协议
3.1、TCP 协议特点与报文格式
3.1.1、TCP 协议的特点
1、TCP 是面向连接(虚连接)的传输层协议。
- 虚连接:与传输层逻辑通信一样,并不是实际的一个物理连接,物理连接指的是把这个数据报加上各个层次的首部后放入到链路上传输,然后再到接收端进行一步一步的解封装,这个是一个完整的物理连接。TCP 协议的使用则好像这两个进程建立了一个点对点的连接,所以说是一种虚连接。
2、每一条 TCP 连接只能有两个端口,每一条 TCP 连接只能是点对点的。
3、TCP 提供可靠交付的服务,无差错、无丢失、不重复、按序到达。【可靠有序,不丢不重】
4、TCP 提供全双工通信。
- 全双工通信两端都可以同时发送、接收数据。
- 对于其特点 TCP 协议连接的两端都会设置有发送缓存(准备发送的队列)以及接收缓存(准备接收的队列)。
发送缓存:准备发送的数据 & 已发送但尚未收到确认的数据。(对于一些已经发送但是还没有收到确认的数据,不能够直接从缓存中删除,因为一旦出现超时的情况那么就需要进行重发)接收缓存:按序到达但尚未被接受应用程序读取的数据 & 不按序到达的数据。(对于每按序到达的数据,只有将数据顺序排好了,接收方才能够逐一一个有一个的来从接收缓存当中取出数据交付给对应的进程)。
5、TCP 面向字节流
- 指的是 TCP 把应用程序交下来的数据看出仅仅是一连串的无结构的字节流。
流:流入到进程或从进程流出的字节序列。
如下图文件包含多个字节,我们将 10 个字节放入到缓存中等待发送:

此时开始发送,可能会先取 3 个字节组成一个 TCP 的报文段,接着在这个报文段上加入 TCP 的首部形成一个完整报文段,再放到链路上进行一个传输,对于这个字节传输的个数根据具体情况不定:

所以说 TCP 协议是面向字节或者说字节流的。
3.1.2、TCP 报文段首部格式
TCP 报文段首部整体描述:
- TCP 报文段由 TCP 首部和 TCP 数据部分组成。
- TCP 首部数据位数要求是 4B 的整数倍,此时就需要 TCP 首部填充一些数据,一般是全 0。
- 首部包含有固定的 20B,对于其他选项、填充字段则是另外计算。

下面是 TCP 首部的 11 个个字段详细描述:
①-②源端口、目的端口:各自占用 2B 也就是 16 位。
③序号位:占用 4B,在一个 TCP 连接中传送的字节流中的每一个字节都按顺序编号,本字段表示本报文段所发送数据的第一个字节的序号。
- 举例 1 中可以看到连续发送的是 1、2、3 字节,那么 TCP 头部中的序号就是 1(传输的第一个字节),表示的是第一个字节。
- 举例 2 中可以看到连续发送的是 4、5、6 字节,那么 TCP 头部中的序号同样也就是 4(传输的第一个字节),表示的是第四个字节。

④确认号:期望收到对方下一个报文段的第一个数据字节的序号。若确认号为 N,则证明到序号 N - 1 为止的所有数据都已正确收到。
- 这个确认号是通过目标方主机发来的。当我们第一个报文传输的字节数 1、2、3 到达时,那么目标方会返回一个确认报文段,此时确认报文段的首部中就包含有一个确认号 = 4,表示的是当前已经收到了 1、2、3 字节,我现在希望收到 4 号字节。

⑤数据偏移(首部长度):TCP 报文段的数据起始处位置 J 距离 TCP 报文段的起始处有多远,以 4B 位单位,即 1 个数值是 4B。
TCP 报文段长度指的是如下图:

由于是以 4B 作为单位,对于数据偏移若是 1111,那么就是 16 x 4B = 64B,当前 TCP 首部就是 64 字节,固定 20B,可选 + 填充就是 44B。
⑥6 个控制位:
对于推送位、复位考试不考,做一个简单了解。
⑦窗口字段:指的是发送本报文段的一方的接收窗口,即现在允许对方发送的数据量。
⑧校验和:检验首部 + 数据,检验时要加上 12B 伪首部,第四个字段(相对应协议字段)为 6。
⑨紧急指针:URG = 1 时才有意义,指出本报文段中紧急数据的字节数。
- 示例:若是紧急指针为 50,那么说明这个 TCP 数据部分从第 1 个字节到 50 个字节,这些都是紧急数据。

10选项:最大报文段长度 MSS、窗口扩大、时间戳、选择确认…。
11填充字段:若是选项字段不是 4B 的整数倍,那么此时就需要进行填充其为 4B 的整数倍。
3.2、TCP 连接管理
3.2.1、TCP 连接传输三个阶段
TCP 连接传输三个阶段:

TCP 连接的建立采用客户 / 服务器方式,主动发起连接建立的应用进程叫做客户,被动等待连接建立的应用进程叫做服务器。
连接时三次握手:

3.2.2、TCP 连接建立过程
3.2.2.1、连接三次握手详解

ROUND1:客户端发送连接请求报文段,无应用层数据。
SYN = 1,seq = x(随机)
- SYN = 1:连接请求时即为 1。
- seq = x(随机):序号位,这个序号是随机产生的,可以从一开始任意一个随机数开始。
- 对于确认号,在这里无效,因为客户端并没有收到服务器端发够来的报文段,因此客户端就不知道自己接下来要期待服务端发来的哪个序号报文段,此时确认号无意义。
对于 SYN 只有两种情况下置为 1,一个是连接请求,另一个是连接请求的确认。
ROUND2:服务端为该 TCP 连接分配缓存和变量,并向客户端返回确认报文段,允许连接,无应用层数据。
SYN=1,ACK=1,seq=y(随机),ack=x+1
- SYN=1:连接请求的接受依旧为 1。
- ACK=1:当 ACK=1 时,此时小写 ack 也有效了,这两个需要进行搭配使用。
- ack=x+1:此时确认号应该填期待对方接下来发送的报文段的第一个字节。由于上次客户端请求的这个序号表示段为 x,此时服务器端想要收到的下一个字节应该是从 x+1 开始。
- seq=y(随机):此时对于确认报文段同样也有一个序号字节,这个序号自己同样也是主机自己随机分配的。
ROUND3: 客户端收到服务端的确认,接下来应该返回一个确认的确认,告诉服务器我们已经建立连接了,接下来就可以给你发送数据,与前两个报文段不同的是,这个第三个报文段可以携带数据了,此时可以将正式要发送的数据放入到报文段。
- 客户端为该 TCP 连接分配缓存和变量,并向服务端返回确认的确认,可以携带数据。
SYN=0,ACK=1,seq=x+1,ack=y+1
- SYN=0:当前并不连接请求,也不是连接请求的确认,此时就是 0。之后所发送的数据 SYN 都为 0。
- ACK = 1:当 ACK=1 时,此时小写 ack 也有效了,这两个需要进行搭配使用。
- seq = x + 1:它所发送的这个报文段的第一个字节是 x+1。
- ack = y + 1:由于上一个 seq 序列想要收到的是 y,那么此时接下来要期待的这个序号就是 y+1。
3.2.2.2、三次握手可能出现的问题:泛洪攻击
对于第二步、第三步中,服务器和客户端都围着 TCP 连接的过程分配了缓存和变量,此时就会导致出现问题:洪泛攻击。
原因:由于三次握手才产生的黑客攻击问题。
攻击描述:SYN 洪泛攻击发生在 OSI 第四层,这种方式利用 TCP 协议的特性,就是三次握手。攻击者发送 TCP SYN,SYN 是 TCP 三次握手的第一个数据包,而当服务器返回 ACK 后,该攻击者就不对其进行再确认,那么这个 TCP 连接就处于挂起状态,也就是所谓的半连接状态。服务器收不到再确认的话,就会重复发送给 ACK 给攻击者,此时就会更加浪费服务器的资源。
- 此时攻击者趁其上面描述进入不断重复发的情况,就继续对服务器发送非常大量的这种 TCP 连接,由于每一个都没法完成三次握手,此时在服务器上,这些 TCP 连接会因为挂起状态而消耗 CPU 和内存,最终服务器可能死机,就无法为正常用户提供服务。
解决 syn 洪泛攻击的办法:设置的是syn cookie。
3.2.3、TCP 的连接释放过程(四次挥手)
关闭连接时四次挥手:

参与一条 TCP 连接的两个进程中的任何一个都能够终止该连接,连接结束后,主机中的 “资源”(缓存与变量)将被释放。

ROUND1:客户端发送连接释放报文段,停止发送数据,主动关闭 TCP 连接。
FIN = 1,seq = u
- FIN = 1:当结束释放连接的时候,此时 FIN 结束位要设置为 1。
- seq = u:指的就是这样一个报文段的第一个字节的序号,由于这个报文段通常其中并没有数据,此时一个序号可以表示这样的一个报文段。
ROUND2:服务器端回送一个确认报文段,客户到服务器这个方向的连接就是释放了。(此时处于半关闭状态)
ACK = 1,seq = v,ack = u+1
- ACK = 1:此时 ack 生效。
- seq = v:取决于它之前发送到哪里,如这个服务器之前上一个发送的报文段,最后一个字节是 v - 1,此时 seq 标为 1。
- ack = u + 1:表示对于上一个报文段的确认,上一个报文 seq = u。
主机收到了这样的一个确认报文段时,不用予以回复,因为这个主机现在已经结束通话了,只需要等待这个服务器告诉它,它也结束,接着它们俩之间的连接就算是正式关闭。
注意:在这个过程中还会发送完剩余数据。
ROUND3:服务器端发送完数据,就发出连接释放报文段,主动关闭 TCP 连接。
FIN = 1,ACK = 1,seq = w,ack = u + 1
- FIN = 1:只要是请求关闭连接,都需要发起 FIN = 1。
- ack = u + 1:由于这个请求关闭连接时在服务器阶段二之后直接进行发送的,中间客户端并没有再发送过请求,此时 ack 回复字段依旧是 u+1,与 ROUND2 中一样,都是进行表示确认。
- seq = v:实际也取决于第二步之后回复确认以后,服务端所发送的数据量多少。
ROUND4:客户端回送一个确认报文段,再等到时间等待时间计时器设置的 2MSL(最长报文段寿命),此时连接彻底关闭。
- 2MSL 指的是最长报文段的寿命。若是确认报文段这没有到达服务器,那么此时服务器没有收到这个会进行重发关闭连接请求,若是在 2MSL 内收到关闭连接请求,那么会进行重新发起确认。
ACK=1,seq = u + 1,ack = w + 1
3.3、TCP 可靠传输
四种 TCP 实现可靠传输的机制
方式一:校验
过程:与 UDP 校验一样,增加伪首部。
- 与 UDP 协议的校验方式一样,都是通过在发送方和接收方增加一个首部,接着通过使用二进制反码求和的计算方法来判断有没有发生错误。
方式二:序号机制
与 UDP 的一样,最终发送的报文段可能就是下面 TCP 缓存中的几个字节,那么序号就表示每个段的第一个字节在整个 TCP 缓存当中的位置:

方式三:确认机制(基于序号机制)
下面我们可以看到当我们 TCP 缓存中的第一段报文在发送到服务端的时候,TCP 缓存里并没有将这个第一段删除掉:

其原因就是要等待服务器端确认之后才进行删除,若是没有收到确认报文那么就可能会出现报文丢失的情况,所以对于发送端如何知道接收方已经正确、完整的接收到了这整个报文,就是靠我们这个确认机制,接收方收到了这个报文段之后,就会返回一个确认报文段。
可以看到当我们服务端返回确认报文时,其中的确认号字段为 4,那么就表示 4 之前的数据已经都完成了接收,那么此时发送端就可以将 TCP 缓存当中的第一段删除:

那如果说有 1、2、3 段,此时中间的第二段迟迟不到(可能已经丢失),对于 1、3 段已经收到了,此时 TCP 默认会使用累计确认,此时确认号字段依旧是 4,也就是服务端告知客户段我下面还是要收到第 4 字节开始的报文:
- 虽然说是顺序接收到,但对于这种情况中间的 2 没到,3 段是也可以进行接收的。

此时客户端就会发送第 2 段报文,也就是 4、5、6,当第 2 段报告发送到服务端时,此时服务端已经接收到了第 1、2、3 段,那么下一次发送确认段中确认号字段为 9。
对于顺序、乱序到达服务端的情况说明:
- 报文段按序完整到达:此时接收方会返回这个确认来指导发送方接下来要发送哪一段报文(顺序到达最后一个报文段末尾的后一位)。
- 报文段没有按序到达:那么接收方会返回一个确认报文段,此时这个报文段就可以指示这个发送方应该重传哪一个报文(中间第一个没有到达的报文段的第一位)。
方式四:重传(RTTS 加权平均往返时间、快速重传机制)
确认、重传机制不分家,TCP 的发送方在规定的时间内(重传时间)没有收到确认那么就要重传已发送的报文段。【超时重传】
问题 1:何时重传?
- 若是发送方超过了一定的时间,还没有收到接收方的确认时,那么发送方就知道自己所发送的这个报文段应该丢失了,此时他就应该将自己这个报文段从缓存中拿出来进行重传。
问题 2:对于这个重传的时间如何进行计算?
- 由于 TCP 下层是一个互联网环境,发送的报文可能会经过高速路的局域网,也有可能经过低速率网络,那么每一个 IP 数据报,它所选择的路由也都是各不相同的,取决于当时的一个网络情况,那么就会导致发送方发送的很多报文段所走的路径都不一样,所以我们不能够设置一个固定的时间。
- 原理:TCP 采用了一种自适应算法来动态改变重传时间,那么这个重传时间叫做
RTTs(加权平均往返时间),也就是当我们发送第一个报文段的时候,这个 RTTs 指的就是取的第一个报文的 RTT(从第一个报文的发送开始知道确认),接着在发送第二段 RTT 时,那么同样会有一个 rtt,接着根据第 1、2 个 rtt 就能够算出一个 RTTs 就作为现在的重传时间。对于之后发送第 N 段 RTT 时,都会设置一个加权的平均往返时间,通过一个公式来计算。
问题 3:若是对于超时重传,若是一直没有到达这个超时时间,那么就会一直进行等待,有没有一种办法能够在超时事件发生之前就能够直到发送方有没有丢失这个报文段,然后尽快的重传呢?
方案:冗余ACK(冗余确认),与确认机制相关。
过程:每当比期望序号大的时序报文段到达时,发送一个冗余 ACK,指明下一个期待字节的序号。
对于下面的情况,可以考单由于在 1 段之后 2 没有收到,此时不断到来的是 3、4、5 此时服务器端也就都会接收,当接收完一个报文段时,实际会发送一个确认号,可以看到在 1 段之后,由于 2 段迟迟没有到来,确认报文段中确认号一直都是 2,可以看到此时这种连续确认号为中间 2 段,那么就是一个冗余确认。当接收端收到了三个相同序号的报文段(是基于 1 的确认为序号 2 之后的连续三个),此时就会就会判断自己发送的这个 2 号报文段发生了丢失情况,此时就会进行重传(此时就实现了提前重传效果)
-
** 为什么能够乱序到达呢?**TCP 中接收端并不是收到一个确认机制发送一个报文段,它时可以进行连续的发送多个报文段的。

这种技术也可以成为:快速重传技术。
3.4、TCP 流量控制
3.4.1、TCP 流量控制产生的原因以及滑动窗口过程
原因:在平时发送数据的时候,通常都会希望这个发送数据的速率可以更快一些,但是如果发送的速率过快,就会使得接收方可能来不及接收,此时就会导致非常严重的丢包现象,此时就需要有流量控制来控制发送方的一个发送速率。
流量控制:让发送方慢点,要放接收方来得及接收。
TCP 利用滑动窗口机制来实现流量控制。
滑动窗口过程:在通信过程中,接收方根据自己接收缓存的大小,动态地调整发送方的发送窗口大小,即接收窗口 rwnd(接收方确认报文段的窗口字段来将 rwnd 通知给发送方),发送方的发送窗口取接收窗口 rwnd 和拥塞窗口 cwnd 的最小值。
- 资源的拥塞情况:网络阻塞了,说明当时网络当中使用网络嗲款,网络资源的主机太多,所以会导致整个网络出现了一个发送缓慢 / 转发缓慢、排队时间过程的一个问题。
- 发送方的发送窗口要取决于接收窗口以及拥塞窗口这两个值的最小值。【发送窗口 = Min{接收窗口,拥塞窗口}】
对于发送方的窗口是可以动态变化的,这个取决于接收方所返回的一个报文段,可能是确认报文,也有可能是一个数据报文,如果窗口字段大,说明现在可以让发送方多发一些数据,若是窗口字段比较小,那么就是让发送方少发一点数据:
- 如下图中,接受返回一个了一个确认报文,其中设置了发送窗口为 6,此时发送方划分出了 6 个窗口的来进行一次发出。

3.4.2、TCP 流量控制详细过程
A 向 B 发送数据,连接建立时,B 告诉 A:“我的 rwnd = 400(字节)”,设每一个报文段 100B,报文段序号初始值为 1。

详细过程描述:
1、首先 A 向 B 进行请求连接建立,接着 B 返回一个确认报文段,其中设置了字段 rwnd = 400(字节)。
2、主机 A 收到确认报文段,此时读取到 rwnd = 400,此时就给自己的发送缓冲区窗口划分了 400 字节(由于报文段 100B,那么就正好是 4 段)。

接着会根据窗口的大小连续的发出了 4 个报文段,每个报文段 100 字节,根据图可以看到前两个报文段主机 B 成功接收,对于第 3 段丢失:

3、此时主机 B 发送了一个确认报文段,其中指明我接下来要接收从 201 字节开始的一个报文段,此时并指明当前可以接收的窗口为 300 字节。

主机 A 的发送窗口是从接收端暂未收到的 201 字节开始,直到 500 字节:

4、此时发送端的发送窗口由于有 300 字节,由于此时 201-300 字节的报文段还没有收到确认报文,此时就会保持在发送窗口,接下来主机 A 发送数据,就可以发送这两个格子里面的数据会从 301 开始,第 3 段,第 4 段,此时就无法发出了,已经窗口最大只能够开大 500 字节。

5、此时对于窗口 201-300 字节的报文段就一直处于僵持的状态,一直在等待接收方发来的确认,等待对于 201-300 字节的报文段超时时间过去之后,就会进行一次重传

6、主机 B 能够成功接收到,此时主机 B 发送了一个响应报文,在响应报文中指明了现在主机 B 想要接收的报文段从 501 开始,发送窗口大小可以限制在 100。


7、主机 A 开始发送 501 字节开始的一段报文段,由于窗口大小只有 100 字节,所以发送完该段就无法继续发送。

8、此时接收端主机 B 返回了一个确认报文段,其中表明说想要从 601 字节开始,发送窗口大小为 0。

由于窗口设置为 0,那么此时发送端就不能在发送数据了。
额外问题 1:若是主机 A 一直在等待主机 B 发送一个非零窗口的通知,而主机 B 发送了一个新的报文段(允许窗口大小为 400)在传输过程中丢失,此时若是没有措施的话,那么主机 A、主机 B 就会一直相互等待,对于这种相互等待的情况,类似于死锁,那么如何解决呢?
解决方案:TCP 为每一个连接设置有一个持续的计时器,只要 TCP 连接的一方收到对方的零窗口通知,就会启动这一个持续计时器。若是计时器到时间,那么主机 A 就会发送一个探测报文段,那么主机 B 会重传这一个通知报文。
- 若是重传的这个通知报文依旧窗口是 0,那么主机 A 会重新再设置一个持续计时器,此时若是在计时器结束之前还是没有通知确认报文的话,那么主机 A 会再发送一个探测报文段,让主机 B 再重传一次。
3.5、TCP 拥塞控制
3.5.2、认识拥塞控制以及与流量控制的区别
什么叫做拥塞控制?
- 在网络当中状况不好,网络发生了阻塞,导致接收数据以及发送数据,整个速度全部降下来了。
出现拥塞的条件:对资源需求的总和 > 可用资源
- 其中的资源指的是:网络当中的一些链路容量,如带宽,一条链路中 50M 带宽,很多人在这条链路上发送数据导致这个链路上的带宽不够这些人使用,那么此时就会导致这个网络出现了拥塞,同时对于交换结点当中的缓存以及交换节点当中的处理机,如路由器当中的处理机等,这些都属于资源。
若是某段时间对于网络当中某一个资源的需求总和超过了这个资源,它可以提供的可用部分,那么网络的性能自然就会变换。此时就会有许多资源同时呈现一个供应不足的情况,从而导致以下的情况发生:
- 网络用有许多资源同时呈现供应不足 —> 网络性能变坏 —> 网络吞吐量将随输入负荷增大而下降。
拥塞控制作用:防止过多的数据注入到网络当中。
- 通过协调使用这个网络资源的所有主机之间的协调就能够防止过多的数据注入到网络当中,此时就可以减轻网络的堵塞情况。
拥塞控制与流量控制的区别:
拥塞控制:假如说下图的上边为接收方,图下边式发送方,都需要给接收方发送数据,那么由于它们同时使用这个网络上的资源,同一个交换结点,那么这个路由器就会使得这个网络非常的繁忙,甚至会出现一个拥塞的情况,对于接收方而言并不知道这种拥塞情况具体是哪一个主机或者是哪几台主机发送速率过快造成的。

流量控制:是一种点对点之间的通信量控制,是一个端到端的问题,如果和这个接收方它手来的这个数据来不及接收了,那么此时就会直到应该照这个发送方。

小结:流量控制这是点到点之间的一个问题,是这个发送方的速率过快导致接收方缓存不够;拥塞控制是一个全局性的问题,主要是因为这个网络发生了阻塞。
3.5.3、拥塞控制的四种算法
3.5.3.1、认识拥塞控制的四种算法
四种算法:慢开始、拥塞避免、快重传、快恢复。
上面的四种是每两个进行搭配使用在一种情形当中,一个是慢开始+拥塞避免,另一个组合是快重传+快恢复:

在学习上面算法之前先进行几个假定:
1、数据单方向传送,而另一个方向只传送确认报文段(并不是传输有效数据进行一个捎带确认)。
- 实际中捎带确认也是比较常见的。
2、接收方总是有足够大的缓存空间,因而发送窗口大小取决于拥塞程度。
发送窗口 = Min(接受窗口rwnd,拥塞窗口cwnd)
- 接收窗口:接收方根据接受缓存设置的值,并告知给对方,反应接收方容量。
- 拥塞窗口:发送方根据自己估算的网络拥塞程度而设置的窗口值,反应网络当前容量。
3.5.3.2、组合一:慢开始和拥塞避免
理解拥塞窗口、传输轮次含义

- 考研中要清楚算法阿德应用过程,对于四种算法的具体细节并不考察。
纵坐标指的是拥塞窗口cwnd,初始值为 1,代表的是一个报文段,一个最大的报文段长度 MSS(此时图中的 4 指的是 4 个 MSS,8 指的是 8 个 MSS),随着传输轮次的增加,拥塞窗口会发生变化。
横坐标指的是传输轮次,一个传输轮次就是一个单位,指的是发送一批报文段并收到他们的确认时间。
- 一个传输轮次:发送了一批报文段收到了它们的确认时间,一个往返时延 RTT。开始发送一批拥塞窗口内的报文段到开始发送下一批拥塞窗口的内的报文段的时间。
传输轮次的理解:
如下:主机 A 给主机 B 发送了一个报文段,此时主机 B 向主机 A 响应了一个报文段,此时就算作一个轮次

由于网络情况很好,此时会多发送几个报文段 m2、m3,此时主机 B 收到两个报文段之后依次返回两个确认,对于这一种情况,到 M3 确认为止,这样的一段就是第二个传输轮次。

此时发送窗口再次进行调大,此时窗口为 4,那么此时可以连续发送 4 个报文段,接着依次收到第 4 个报文段的时候此时就算作第三个传输轮次:

慢开始和拥塞避免的详细过程
慢开始指的是一个指数规律增长,一个爆炸式增长的过程。
- 慢的原因主要是一开始注入的仅仅只是一个报文,这对于初始注入很多报文段来说,会慢很多。
过程:首先对这个网络进行一个探查,看一下这个网络的拥塞情况,若是比较好,那么此时就增加我的拥塞窗口发送方,增加拥塞窗口,这个倍数是 2 倍,分为四个阶段。
①一开始是进行 【慢开始】,在第一个传输轮次是 1 个 MSS,第二个传输轮次是 2 个 MSS,第三个传输轮次是 4 个 MSS,第四个传输轮次是 16 个 MSS,此时可以看到已经到达了 ssthresh 的初始值 16,其指的是一个**慢开始门限 **。

②此时就会由慢开始进入到 【拥塞避免】,因为目前现在注入的报文段比较多,此时会担心之后很快会发生拥塞情况,此时就把速度稍微降一降。此时会在之前的拥塞窗口基础上,每次增加一个拥塞窗口,可以看到在 5 个轮次到 12 个轮次每次都是 + 1,此时一直到了 24 个 MSS。
- 慢开始门限:一旦到了这个慢开始门限初始值时,速度就要稍微减一点,会由慢开始进入到拥塞避免。
- 拥塞避免过程:是线性增长的过程,在慢开始门限基础上每次 + 1。

③由于到达了 24MSS 时,此时网络出现了拥塞,发生了丢包情况,此时会重新进入到 【慢开始状态】,拥塞窗口重新回到了 1,瞬间从 24 个报文段缩减为 1 个报文段,之后的过程就是继续开始执行慢开始,1、2、4、8,接着在第 17 个轮次时,注意此时的门限值变为了 12。
- ** 新的门限值如何确定?** 根据当前出现了网络拥塞的情况下出现的,一旦出现网络拥塞,就会立即将拥塞窗口 / 2,由于之前出现网络拥塞的拥塞窗口为 24,那么此时 24/2 = 12,那么此时新的门限值就是 12。

④当进入到 【拥塞避免】 状态时,还是会进行线性增长,每次 + 1,之后的过程都是一样一旦出现网络拥塞,那么会设置新的门限值,并重新回到慢开始进行。

3.5.3.3、组合二:快重传和快恢复
快重传出现的原因主要是解决对于等待超时时间过长而实现的一种机制,机制过程如下:
- 此时连续发送了 M1、2、3、4、5 这五个报文段,当 M1 发送到 B 后,此时会返回一个确认号,其中 ack=2,表示要收到第 2 个报文,报文 2 丢失,紧接着 B 又收到了 M3、4、5 的确认报文段其中 ack=2,那么此时就是累计有四个 ack=2 的确认报文段了,基于对于最后三个相同 ack=2 的那么就被成为冗余 ack,此时主机 A 会进行重新发送 M2 报文。

** 快恢复是如何体现的呢?** 可以看到下图中在 12 抡次时拥塞窗口为 24 时,由于收到了 3 个重复的确认后执行了【快重传】,紧接着就会进入到【快恢复状态】,此时并不用降低拥塞窗口为 1MSS 情况,此时就会降到新的一个门限值,此时在这个 12 的门限值阶段我们进行【拥塞避免】进行线性加法增大。
- ** 门限值如何确定?** 此时就是将出现重复确认的时候,将此时这个拥塞窗口 24/2=12,紧接着我们就进行快恢复。

** 什么是快恢复?** 不用降到 1,直接降到新的门限值(出现快重传的拥塞窗口 / 2),接着使用拥塞避免的算法。
对于图中的 TCP-Tahoe 版本已经废弃,该版本应该就是在出现快重传的时候,此时拥塞窗口直接变为了慢开始的初始阶段 1,之后就执行相应的策略。
整理者:长路 时间:2023.8.7-8