计算机网络:第五章 - 传输层 594次阅读 计算机网络 2022-09-09 目录 [TOC] ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/SplitLine/SplitLine-01.gif) # 一、传输层概述 ## (一)传输层 为应用层提供通信服务,使用网络层服务,只有主机才有的层次。 ### 1、传输层功能 * 传输层提供**进程和进程**之间的逻辑通信。 * 复用和分用。 * 复用:指发送方不同的应用进程都可以使用同一个传输层协议传送数据; * 分用:指接收方的传输层在剥去报文的首部后能够把这些数据正确交付到目的应用进程。 * 传输层对收到的报文进行差错检测(首部和数据部分)。 * 传输层的两种协议:TCP、UDP。 ### 2、传输层的两个协议 #### (1)面向连接的传输控制协议 TCP * 传送数据之前必须建立连接,数据传送结束后要释放连接。不提供广播或多播服务。由于 TCP 要提供可靠的面向连接的传输服务,因此不可避免增加了许多开销:确认、流量控制、计时器及连接管理等。 * 可靠,面向连接,时延大,适用于大文件。 #### (2)无连接的用户数据报协议 UDP: * 传送数据之前不需要建立连接,收到 UDP 报文后也不需要给出任何确认。 * 不可靠,无连接,时延小,适用于小文件。例如微信发信息。 ## (二)传输层的寻址与端口 ### 1、通信过程分析 * 如果要发送数据给一个主机,只需要知道它的 IP 地址,就能寻找到主机所在的网络; * 进入所在网络后可以根据 MAC 地址定位到具体的主机(网络层); * 找到主机后,还需要找到主机中接收该数据的进程(传输层)。 * 如何找到该进程呢?——根据端口(逻辑端口) ### 2、端口 * 端口是传输层的 SAP(服务访问点/接口),标识主机中的应用进程。 > 1、该端口为逻辑端口/软件端口,要和硬件端口区分开 > > * 软件端口:是应用层的各种协议进程与传输实体进行层间交互的一种地址。 > * 硬件端口:不用硬件设备交互的接口(像路由器、交换机这种直接插上去的端口)。 > > 2、SAP:服务访问点/接口 > > * 数据链路层 SAP:MAC 地址 > * 网络层 SAP:IP 地址 > * 传输层的 SAP:端口 > ### 3、端口号 端口由具体的数字标识叫做端口号,端口号**只有本地意义**,在因特网中不同计算机的相同端口是没有联系的。 #### (1)端口号范围 端口号长度为 16bit,能表示 216=65536 个不同的端口号。 ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%281.2.3.1_1%29.png) #### (2)常用应用程序端口号: ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%281.2.3.2_1%29.png) #### (3)套接字 * 在网络中采用发送方和接收方的套接字组合来识别端点,**套接字唯一标识了网络中的一个主机(IP 地址标识网络中每一个主机)和它上面的一个进程(端口号标识主机中的进程)。** * **套接字 Socket= ( 主机 IP 地址,端口号):**根据 IP 地址可以找到主机,根据端口号可以找到主机中的具体进程。 > MAC 地址也是根据 IP 地址找到的 > ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/SplitLine/SplitLine-01.gif) # 二、UDP 协议(User Datagram Protocol) UDP(User Datagram Protocol):用户数据报协议 ## (一)UDP 数据报 ### 1、UDP 概述 UDP 只在 IP 数据报服务之上增加了很少功能,即:复用分用和差错检测功能。 UDP 的主要特点: * UDP 是无连接的,减少开销和发送数据之前的时延。 * UDP 使用最大努力交付,即**不保证可靠交付**。(由应用层保证可靠交付) * UDP 是**面向报文**的,适合一次性传输少量数据的网络应用(如:DNS、SNMP)。 > (应用层给 UDP 多长的报文,UDP 就照样发送,即一次发一个完整报文。在传输层称为报文段。如果数据太大,在传给网络层时还要分片,所以适合一次传输少量数据。) > * UDP 无拥塞控制,适合很多实时应用。 * UDP 首部开销小,首部大小为 8B。而 TCP 首部为 20B。 * UDP 支持一对一、一对多、多对一、多对多的交互通信。 ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%282.1.1_1%29.png) ### 2、UDP 首部格式 ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%282.1.2_1%29.png) UDP 首部字段(8B): * 源端口号:可有可无,在需要对方回信时选用。不需要时可用全 0. * 目的端口号:在终点交付报文时必须要使用到。 * UDP 长度:UDP 数据报的长度(包括首部和数据),其最小值是 8B(仅有首部)。 * UDP 校验和:检验 UDP 数据报在传输中是否有错。有错就丢弃。该字段是可选的,当源主机不想计算校验和时,则直接令该字段为全 0。 还有一种出错情况:分用时,找不到对应的目的端口号,就丢弃报文,并给发送方发送 ICMP“端口不可达”差错报告报文。 ## (二)UDP 校验 在计算校验和时,要在 UDP 数据报之前增加 12B 的伪首部,伪首部并不是 UDP 的整整首部。 只是在计算校验和时,临时添加在 UDP 数据报的前面,得到一个临时的 UDP 数据报。校验和就是按照这个临时的 UDP 数据报来计算的。 ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%282.2_1%29.png) ### 1、伪首部 伪首部既不向下传送又不向上递交,而只是为了计算校验和。 * 0 字段:固定部分,全 0。 * 17 字段:封装 UDP 报文的 IP 数据报首部协议字段是 17。 > IP 数据报首部的协议字段,在说明数据部分使用的是什么协议 > * UDP 长度:UDP 首部 8B+ 数据部分长度(不包括伪首部) ### 2、如何用伪首部校验 UDP 数据报有没有发送差错 ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%282.2.2_1%29.png) #### (1)在发送端: 1. 填上伪首部; > 伪首部只有在计算检验和时才出现 > 2. 先首部**校验和字段**填充全 0; 3. 全 0 填充数据部分; > 目的是要让 UDP 数据报要看成许多 4B 的字串接起来 > 4. 伪首部 + 首部 + 数据部分采用二进制反码求和; > 此时校验和字段全 0 > 5. 把和求反码填入**检验和字段**; 6. 去掉伪首部,发送。 > 二进制反码求和具体来说就是: > > 0+0=0 > > 1+0=0+1=1 > > 1+1=10 > > 其中 10 中的 1 加到了下一列去,如果是最高列的 1+1,那么得到的 10 留下 0,1 移到最低列,与最低位再做一次二进制加法即可。 #### (2)在接收端 1. 填上伪首部 2. 伪首部 + 首部 + 数据部分采用二进制反码求和 > 此时校验和字段有值 > 3. 结果全为 1 则无差错,否则丢弃数据报/交给应用层附上出差错的警告。 ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/SplitLine/SplitLine-01.gif) # 三、TCP 协议(Transmission Control Protocol) TCP(Transmission Control Protocol):传输控制协议 ## (一)TCP 协议特点和 TCP 报文段 ### 1、TCP 协议特点 1. TCP 是面向连接(虚连接,并不是物理连接)的传输层协议。打 call 2. 每一条 TCP 连接只能有两个端点,每一条 TCP 连接只能是点对点的。(无法用于广播或多播) 3. TCP 提供可靠交付的服务,无差错、不丢失、不重复、按序到达。可靠有序,不丢不重 4. TCP 提供全双工通信。 * 发送缓存:准备发送的数据&已发送但尚未收到确认的数据 * 接收缓存:按序到达但尚未被接受应用程序读取的数据&不按序到达的数据 5. TCP 面向字节流:TCP 把应用程序交下来的数据看成仅仅是一连串的**无结构的字节流**。字节流中的每一个字节都按顺序编号。 * 流:流入到进程或从进程流出的字节序列。 ### 2、TCP 报文段首部格式(重点,单位 4B) TCP 传送的数据单元称为报文段。 ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%283.1.2_1%29.png) #### (1)固定首部(20B) 1. **源端口:**2B 2. **目的端口:**2B 3. **序号 seq:4B;** * 在一个 TCP 连接中传送的**字节流**中的每一个字节都按顺序编号。 * 本字段表示本报文段所发送数据的**第一个字节的序号。** > **一起来吃饭的一组人按顺序每个人分个号,但进去的时候只看第一个人的序号。** > > ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%283.1.2.1_1%29.png) > > TCP 头就是 TCP 首部。 > 4. **确认号 ack:4B;** **期望**收到对方下一个报文段的第一个数据字节的序号。 若确认号为 N,则证明到序号 N-1 为止的所有数据都已正确收到。 > **服务员确认一下下一组人的第一个人是几号。** > 5. **数据偏移(首部长度) : 4 位;** TCP 报文段的数据起始处距离 TCP 报文段的起始处有多远,以 **4B 位单位**,即 1 个数值是 4B。 > 例如数据偏移是 1111,10 进制数是 15,15*4B=60B。说明 TCP 首部长度为 60B。 > 6. **保留:6 位;** 保留今后使用,但目前应置为 0。 7. **六个控制位:** 1. **紧急位 URG**:URG=1 时, 标明此报文段中有紧急数据,是高优先级的数据,应尽快传送,不用在缓存里排队,配合**紧急指针字段**使用。 即,不用在缓存里排队。 > **这组人有会员,先进去** > 2. **确认位 ACK**:ACK=1 时确认号有效,在连接建立后所有传送的报文段都必须把 ACK 置为 1。 > **拿到号后,服务员必须给号盖章** > 3. 推送位 PSH:PSH=1 时, **接收方尽快交付**接收应用进程,不再等到缓存填满再向上交付。 > **进去以后,有一组人很急,要先吃** > 4. 复位 RST:RST=1 时,表明 TCP 连接中出现严重差错,必须释放连接,然后再重新建立传输链接。 还可以用来拒绝一个非法的报文段或拒绝打开一个链接。 > **之前号码作废,重新取号** > 5. **同步位 SYN**: SYN=1 时,表明是一个连接请求报文或连接接受报文。 > **我和服务员说取个号 / 服务员把号给我** > 6. **终止位 FIN**:FIN=1 时, 表明此报文段发送方数据已发完,要求释放连接。 > **一组人已经进去了,号可以作废了** > 8. **窗口:2B;** 指的是发送本报文段的一方的接收窗口,即现在允许对方发送的数据量。 接收方的接收窗口大小。 9. **检验和:2B;** 检验首部 + 数据,检验时要加上 12B 伪首部。 > 只需要将 UDP 伪首部的第四个字段,即协议字段的 17 改成 6,其他的和 UDP 一样。 > 10. **紧急指针:2B;** URG=1 时才有意义,指出本报文段中紧急数据的字节数。 > **是会员时,查看会员人数** > #### (2)选项(长度可变) 最大报文段长度 MSS、窗口扩大、时间戳、选择确认... #### (3)填充 全 0,保证 TCP 首部是 4B 的倍数,填充 + 选项=4B。 ## (二)TCP 连接管理 **TCP 连接传输三个阶段:连接建立 —> 数据传送 —> 连接释放** ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%283.2_1%29.png) ![image-20211018204248865](assets/image-20211018204248865-20220810150918-okojt10.png) ### 1、TCP 连接建立(三次握手) ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%283.2.1_1%29.png) TCP 连接的建立采用**客户服务器方式**,主动发起连接建立的应用进程叫做**客户**,而被动等待连接建立的应用进程叫**服务器**。 假设运行在一台主机(**客户**)上的一个进程想与另一台主机(**服务器**)上的一个进程建立一条连接,客户应用进程首先通知客户 TCP,他想建立一个与服务器上某个进程之间的连接,客户中的 TCP 会用以下步骤与服务器中的 TCP 建立一条 TCP 连接: ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%283.2.2_1%29.png) #### TCP 连接建立过程: ROUND 1: * **客户端**发送**连接请求报文段**,无应用层数据。 * SYN=1 > 同步位:SYN=1 时,表明是一个连接请求/连接接受报文 > * seq=x > 序号字段:随机分配,表示**连接请求报文段**第一个字节的序号 > ROUND 2: * **服务器端**为该 TCP 连接分配缓存和变量,并向客户端返回**确认报文段**,允许连接,无应用层数据。 * SYN=1; * ACK=1; > 确认位:ACK=1 时确认号有效,连接建立后所有传送的报文段都必须把 ACK 置为 1 > * seq=y; > 序号字段:随机分配,**确认报文段**也有序号字段 > * ack=x+1; > 确认号字段:因为客户端的**连接请求报文段**第一个字节的序号为 x,表示期待客户端接下来的**发送报文段**的第一个字节的**序号为 x+1** > ROUND 3: * **客户端**为该 TCP 连接分配缓存和变量,并向服务器端**返回确认的确认报文段**,可以**携带数据**。 * SYN=0; > 发送连接请求报文/连接接受报文时 SYN 才为 1 > * ACK=1; * seq=x+1; > 序号字段:因为客户端之前的**连接请求报文段**第一个字节序号为 x,下一个**发送报文段**就是 x+1 > * ack=y+1; > 确认号字段:因为服务端上次发来的**确认报文段**第一个字节序号是 y,所以期待下一个**服务端确认报文段**的第一个字节的序号为 y+1 > ### 2、SYN 洪泛攻击 SYN 洪泛攻击发生在 OSl 第四层,这种方式利用 TCP 协议的特性,就是三次握手。 攻击者发送 TCP SYN(SYN 是 TCP 三次握手中的第一个数据包), 而当服务器返回 ACK 后, 该攻击者就不对其进行再确认,那这个 TCP 连接就处于挂起状态,也就是所谓的半连接状态,服务器收不到再确认的话,还会重复发送 ACK 给攻击者。这样更加会浪费服务器的资源。 攻击者就对服务器发送非常大量的这种 TCP 连接,由于每一个都没法完成三次握手,所以在服务器上,这些 TCP 连接会因为挂起状态而消耗 CPU 和内存,最后服务器可能死机,就无法为正常用户提供服务了。 解决办法:设置 SYN cookie ### 3、TCP 的连接释放(四次握手) ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%283.2.3_1%29.png) 参与一条 TCP 连接的两个进程中的任何一个都能终止该连接,连接结束后,主机中的“资源”(缓存和变量)将被释放。 ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%283.2.3_2%29.png) ROUND 1: * **客户端**发送**连接释放报文段**,停止发送数据,主动关闭 TCP 连接。 * FIN=1; > 终止位:FIN=1 时, 表明客户端数据已发完,要求释放连接。 > * seq=u; > 序号字段:客户端发送的连接释放报文段的第一个字节序号为 u,随机分配 > ROUND 2: * **服务器端**回送一个**确认报文段**,客户到服务器这个方向的连接就释放了一一但目前只处于半关闭状态,因为服务器还可以发送数据。 * ACK=1; > 确认位:ACK=1 时确认号有效 > * seq=v; > 序号字段:服务端发送的确认报文段的序号为 v,随机分配 > * ack=u+1; 确认号字段:客户端发上次发来的**连接释放报文段**序号是 u,期待客户端的下一个数据报的序号是 u+1 ROUND 3: * **服务器端**发完数据,就发出 **< 连接释放报文段**,主动关闭 TCP 连接。 * FIN=1; > 终止位:FIN=1 时, 表明服务端数据已发完,要求释放连接。 > * ACK=1; * seq=w; > 序号字段:服务端发送的连接释放报文段的序号为 w,因为这个报文段又是服务端自己发送的,所以序号又要随机分配 > * ack=u+1; > 确认号字段:为什么和确认报文段一样呢?因为客户端没发送数据,所以继续期待客户端的下一个数据报的序号是 u+1 > ROUND 4: * **客户端**回送一个**确认报文段**,再等到时间等待计时器设置的 2MSL (最长报文段寿命)后,连接彻底关闭。 * ACK=1; * seq=u+1; > 序号字段:客户端回送的**确认报文段**的序号为 u+1,正如服务端期待的一样 > * ack=w+1; > 确认号字段:服务端上次发来的**连接释放报文段**序号是 w,期待服务端的下一个数据报的序号是 w+1 > 个人理解:确认号字段是对对方数据报序号的下一个期待。序号字段第一次由自己随机分配序号,在之后的互相发送过程中,序号字段按照对方期待的来填写。 ## (三)TCP 可靠传输 * 传输层:使用 TCP 实现可靠传输(UDP 依靠应用层实现可靠传输) * 网络层:提供尽最大努力交付,不可靠传输 **可靠数据传输服务:**保证接收方进程从缓存区读出的字节流与发送方发出的字节流是完全一样的。 ### 1、TCP 实现可靠传输的四种机制 #### (1)校验机制 与 UDP 校验一样,增加伪首部,通过使用二进制反码求和的方法来判断是否发生错误。 #### (2)序号机制 ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%283.3.1.2_1%29.png) TCP 首部的序号字段用来保证数据能有序提交给应用层。 TCP 把数据视为一个无结构但有序的字节流,序号建立在传送的字节流之上,而不建立在报文段之上。TCP 连接传送的数据流中的每一个字节都编上一个序号。 > 虽然说 TCP 是面向字节流的,但是实际发送时,是把一些字节放一起组成报文段。报文段大小是不定的。 #### (3)确认机制 > 发送方如何找到接收方正确完整接收到 123 报文段呢? ——确认机制。 ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%283.3.1.3_1%29.png) TCP 首部的确认号是期望收到对方的下一个报文段的数据的第一个字节的序号。 接收方:接收报文段后会返回一个确认报文段。 > 首部确认号字段为 4,期待下一个字节序号是 4 发送方:收到确认报文段后,缓存区内的已确认报文段删除。 发送方缓存区会继续存储那些已发送但未接到确认的报文段,以便在需要时重传。 > 知道接收方正确接收了,就可以把 123 报文段从 TCP 缓存中删去。 TCP 默认使用累计确认,即,TCP 只确认数据流中至第一个丢失字节为止的字节。 > 发送方继续发送 456、78 报文段,而 456 报文段没到达接收方,TCP 使用累计确认,所以接收方确认报文段的首部确认号字段仍然为 4。 > > 发送方接收到确认报文段后,会重传 456 报文段。接收方收到 456 报文段后,给发送方发送首部确认号为 9 的确认报文段。 #### (4)重传机制 有两种事件会导致 TCP 对报文段进行重传,超时和冗余 ACK。 ##### ① 超时重传 > 如果一直收不到确认报文段怎么办呢?——超时 TCP 每发送一个报文段,就对这个报文段设置一个计时器。计时器设置的重传时间到期但还未收到确认时,就要重传这一报文段。 TCP 采用自适应算法,记录一个报文段发出的时间,以及收到相应确认的时间,这两个时间差成为报文段的往返时间(RTT)。 TCP 保留了一个 RTT 的一个加权平均往返时间 RTTs(加权平均往返时间),会随着新测量 RTT 样本值动态改变。 > 发送第一个报文段时,RTT~s~取的是第一个报文段的 RTT(从它发送到收到确认的时间);然后取第二个报文段的 RTT......通过公式可以动态计算各报文段加权平均往返时间。 超时计时器设置的超时重传时间(RTO)应略大于 RTTs。 ##### ② 冗余 ACK > 有没有什么办法,在超时事件发生之前,就知道发送方有没有丢失报文段,可以尽快重传?——冗余 ACK(冗余确认) TCP 规定,每当比期望序号大的失序报文段到达时,发送一个**冗余 ACK**,指明下一个期待字节的序号。 > 举例:发送方已发送 1,2,3,4,5 报文段 > > * 接收方收到 1,返回给 1 的确认(确认号为 2 的第一个字节) > * 接收方收到 3,仍返回给 1 的确认(确认号为 2 的第一个字节) :可以看到,如果发生了失序,还是按照失序前返回确认。 > * 接收方收到 4,仍返回给 1 的确认(确认号为 2 的第一个字节) > * 接收方收到 5,仍返回给 1 的确认(确认号为 2 的第一个字节) > * 发送方收到 **3 个对于报文段 1 的冗余 ACK** ——> 认为 2 报文段丢失,重传 2 号报文段,此技术称为**快速重传技术**。 ### 2、TCP 的窗口和协议 * 滑动窗口,停等协议、GBN 协议、SR 协议等在链路层已经讲过,原理差不多。 * 根据上面所讲的冗余确认可以看出,TCP 常使用的是 GBN、SR 协议。 ## (四)TCP 流量控制 ### 1、流量控制 TCP 提供流量控制服务来消除发送方(发送速率太快)使接收方缓存区溢出的可能性,是一个速度匹配服务(匹配发送方的发送速率与接收方的读取速率)。 > 流量控制:让发送方慢点,要让接收方来得及接收。 TCP 利用**滑动窗口机制**实现**流量控制**。 在通信过程中, * **接收窗口 rwnd**,接收方根据自己目前**接收缓存的大小**,动态地调整发送方的发送窗口大小,**反应接收方的容量**。 > 接收方调整确认报文段的**“窗口 ”字段值**来将 rwnd 通知给发送方,来限制其向网络注入报文的速率。 > * **拥塞窗口 cwnd**,发送方根据自己估算的网络拥塞程度而设置的窗口值,**反应网络的当前容量**。 * 发送方的**发送窗口 swnd** 取接收窗口 rwnd 和拥塞窗口 cwnd 的最小值。 即,发送窗口值 = min { 接收窗口 rwnd,拥塞窗口 cwnd } ### 2、流量控制过程 A 向 B 发送数据,连接建立时,B 告诉 A:“ 我的 rwnd=400 (字节)”,设每一个报文段 100B,报文段序号初始值为 1。 ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%283.4.2_1%29.png) TCP 采用的是累计确认,并不使用停等协议。 主机 A 给 B 发送了几个报文段,主机 B 才给 A 发送一个确认报文段。 TCP 流量控制可以看做**累计确认 +SR 选择重传协议 + 动态调整接收窗口**。 ### 3、持续计时器 > 主机 B 给主机 A 发送确认报文段中窗口字段为 rwdm=0(零窗口)时,主机 A 不能再发送数据给主机 B,而主机 B 又在等主机 A 发送数据,于是主机 A 和 B 互相死等,此时就会造成类似操作系统中的死锁现象。 > > 如何解决?——持续计时器 * TCP 为每一个连接**设有一个持续计时器**,只要 TCP 连接的一方收到对方的**零窗口**通知,就启动持续计时器。 * 若持续计时器设置的时间到期,就发送一个**零窗口探测报文段**。接收方收到探测报文段时给出现在的窗口值。 * 若窗口仍然是 0, 那么发送方就重新设置持续计时器。 * 在持续计时器设置的时间内,接收方有可能会给发送方一个非零窗口通知。 ### 4、传输层与数据链路层的流量控制的区别 传输层: * 定义端到端用户之间的流量控制; * 滑动窗口协议的窗口大小可以动态变化; 数据链路层: * 定义两个中间的相邻结点的流量控制; * 滑动窗口协议的窗口大小不可动态变化 ## (五)TCP 拥塞控制 ### 1、拥塞控制 ##### (1)出现拥塞的条件 对资源需求的总和 > 可用资源 ##### (2)拥塞导致的问题: 网络中有许多资源同时呈现供应不足 ——> 网络性能变坏 ——> 网络吞吐量将随输入负荷增大而下降 ##### (3)拥塞控制目的: 防止过多的数据注入到网络中。这是一个全局性问题。 ##### (4)拥塞控制与流量控制的区别: **拥塞控制**是多台主机同时使用网络资源给一个接收方发送数据,使得网络非常繁忙,接收方不知道是哪个主机的问题,拥塞控制是一个全局性问题。 **流量控制**是点对点问题,让发送方发慢点。 ### 2、拥塞控制四种算法 * **慢开始 拥塞避免** * **快重传 快恢复** 为了方便讨论,假定如下: 1.数据单方向传送,而另一个方向只传送确认(实际传输数据是双向的) 2.接收方总是有足够大的缓存空间,因而发送窗口大小取决于拥塞程度 * 前面学过,发送窗口=Min{ 接收窗口 rwnd,拥塞窗口 cwnd },这里假设接收窗口足够大,因而发送窗口大小取决于拥塞程度。 ### 3、慢开始和拥塞避免算法 ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%283.5.3_1%29.png) #### (1)慢开始算法 TCP 已连接好,并开始发送 TCP 报文段,此时: * **拥塞窗口 cwnd 初值:**默认为 1,即 **cwnd = 1** > 为了讨论方便,这里的 1,不是一个字节而是一个报文段,报文段的长度是一个最大报文段长度 MSS。 > > 用此方法逐步增大发送方的 cwnd,使分组注入网络的速率更加合理。 > **慢开始算法:** * 拥塞窗口指数规律增长,拥塞窗口在发送方收到确认报文时增长。 即,每一次传输轮次结束,cwnd 的大小就会加倍(乘 2,指数式增长) * 传输轮次: * 发送了一批报文段并收到它们的确认的时间。 即,一个往返时延 RTT。 * 开始发送一批拥塞窗口内的报文段到开始发送下一批拥塞窗口内的报文段的时间。 > 慢开始的“慢 ”,并不是指拥塞窗口 cwnd 的增长速率慢,而是指在 TCP 开始发送报文段时先设 cwnd=1,使发送方最开始只发送一个报文段,用于试探一下网络的拥塞情况,然后逐轮增大。 当 cwnd 增大到一个规定的慢开始门限(ssthresh 值),然后改用拥塞避免算法。 #### (2)拥塞避免算法 > 拥塞避免不能安全避免拥塞,只是为了使网络中不容易出现拥塞。 每经过一个往返时延 RTT 就把发送方的 cwnd 加 1,使其按线性规律缓慢增大。 根据成为你的的大小执行不同的算法: * 当 cwnd < ssthresh 时,使用慢开始算法。 * 当 cwnd > ssthresh 时,停止使用慢开始算法而改用拥塞避免算法。 * 当 cwnd = ssthresh 时,既可使用慢开始算法,也可使用拥塞控制避免算法。 #### (3)网络拥塞的处理 无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞(未按时收到确认), * 就要把慢开始门限 ssthresh 设置为出现拥塞时发送方 cwnd 值的一半(但不能小于 2)。 * 然后重新把 cwnd 设置为 1,执行慢开始算法。 在慢开始阶段,若 2cwnd > ssthresh ,则下一个 RTT 后的 cwnd = ssthresh。 即,cwnd 不能越过 ssthresh 值。 #### (4)“加法增大”和“乘法减小”的含义 “加法增大”: * 指执行拥塞避免算法后,在收到对所有报文段的确认后,就把 cwnd 增加一个 MSS 大小,使拥塞窗口缓慢增大,以防过早出现网络拥塞。 “乘法减小”: * 指无论是在慢开始阶段还是在拥塞避免阶段,只要出现超时,就 ssthresh 值设置为当前 cwnd 的一半,并执行慢开始算法 #### (5)现实中的看 ssthresh TCP 本身是自适应的,它并没有规定 ssthresh 的值的大小,甚至都没有建议。ssthresh 初始值按需求而定。 ### 4、快重传和快恢复算法 > 这两个算法是对前两个算法的改进。 ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/%E6%8A%80%E6%9C%AF%E5%9F%9F/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C/Unit5/CNET.Unit5.%283.5.4_1%29.png) #### (1)快重传算法 使用快速重传技术。 发送方收到 **3 个重复的冗余 ACK** 报文 ——> 认为该报文段丢失,直接重传该报文段。 在超时计时器之前执行快重传可以实现快速重传报文段。 > 快重传并没有取消重传计时器,而是在某些情况下更早地重传失去的报文段。 #### (2)快恢复算法 原理如下: * 当发送方连续收到三个冗余 ACK(即重复确认)时,执行乘法减小算法,把 ssthresh 设置为此时发送方 cwnd 的一半。 * 然后直接开始执行拥塞避免算法。 ### 5、四种算法总结 * 在流量控制中,发送方发送数据的量由接收方决定; * 在拥塞控制中,则有发送方自己通过检查网络状况来决定。 四种算法是同时应用在拥塞控制机制中的。 * 在 TCP 连接建立和网络出现超时时,采用慢开始和拥塞避免算法; * 当发送方接收到冗余 ACK 时,采用快重传和快恢复算法。 > 接收方的缓存空间总是有限的。 > > 因此,发送方发送窗口的实际大小由流量控制和拥塞控制共同决定。 > > 当题目中同时出现 rwnd 和 cwnd,哪个小 swnd 取值哪个 ![](https://picture-host-1304031833.cos.ap-beijing.myqcloud.com/SiYuan/SplitLine/SplitLine-01.gif) # 参考资料 > **版权声明**:个人学习记录,本博客所有文章均采用 CC-BY-NC-SA 许可协议。转载请注明出处!若有侵权,请留言联系! > > * 2022 天勤计算机考研高分笔记-计算机网络 > * 2022 王道计算机考研复习指导-计算机网络 如果您觉得文章对您有帮助,请点击文章正下方的小**红心**一下。您的鼓励是博主的最大动力! 2 最后一次更新于2022-10-23 计算机网络
0 条评论