传输层(王道视频笔记)

第5章 传输层



前言

在这里插入图片描述

  • 我们通信的时候 虽然都说是主机之间的通信 但实际上是主机之间的进程和进程通信
  • 比如说我给你发微信 那其实就是我手机当中正在运行的这个微信程序 也就是这个进程在跟你手机当中的微信这样一个进程进行通信,行一个数据的传输 所以这一章传输层 我们就是主要研究进程之间的逻辑通信问题
  • 首先我们要学习一下传输层的概述 就是一些基本的概念 包括它的功能特点等等 那么对于每一个层次 其实我们都要学习它的一些协议
  • 因为协议是规定网络体系结构当中每一个层次的一些重要功能 那在传输层的我们主要学习两种协议 TCP协议和UDP协议
  • 那在计算机网络当中 有一个非常重要的问题 就是我们在进行数据通信资源共享的过程当中 如何来保证我们这个数据是准确的呢?或者说 在一种可能会丢失或者是损坏的数据媒体上面 如何可靠的来传输我们的数据 那这个就是TCP协议发挥作用的地方
  • 通过使用TCP协议 我们可以实现可靠传输 同时还可以实现一定的流量控制和拥塞控制等等
  • 那么TCP协议和UDP协议相比起来 它就是一个不太可靠的协议,那么 在传输一些可能对于这个数据的准确性要求不是很高,在传输延迟方面可能要求比较苛刻的一些场景下 我们通常会使用UDP的协议

5.1.1 传输层概述

传输层

在这里插入图片描述

  • 那传输层 它是作为只有主机才会有的层次,也就是在端系统两个主机之间才会有一层叫传输层 那最高层 如果是五层结构的话 就到应用层,而中间的这些网络设备 他们最多 只能到网络层 也就是最多只有三个层次 因此是到不了传输层的
  • 传输层是为应用层提供服务 同时 它也可以使用网络层的服务
  • 在实际应用的时候,在实际通信的时候 比如说我们的qq或者是微信,在聊天的时候,如果这个数据只知道了这个主机还没有通信结束,只有把这个数据送交到某一个具体的进程 或者说这个进程的具体的一个窗口,也是进程当中的一个具体线程的时候 我们才能够实现这个通信的过程 所以说到网络层 这个通信是没完成的,还要再到传输层 也就是实现一个进程和进程之间的逻辑通信
  • 那之所以是逻辑通信 就好像表面上啊,是两个主机的进程之间在通信 我的qq在跟你的qq通信 实际在通信的时候 是把数据从最上层,进行一步又一步的封装 传给下层 也就是到了物理层 然后 物理层再放到链路上传输,那到了对端 就要经过物理层再自下而上的,把这个数据解封装 然后再交付给最终的应用层
  • 所以我们说传输层 它提供的是进程与进程之间的一个逻辑通信 而网络层的提供的是主机与主机之间的逻辑通信
  • 这个复用指的是发送方不同的应用进程 比如说qq或者微信,他们都可以使用同一个传输层的协议来传送数据 而这个分用 指的是接收方 它传输层在播去报文的首部之后能够把这些数据,送交给正确的一些进程
  • 复用和分用的过程 其实就好比我们生活当中寄信的一个例子,假如说我们家里有四口人 那这四个人 分别都想给他们的好朋友写信 那我们就会把这些信写好之后放到家门口的信箱当中,再由邮局小哥把信箱当中的信,收集好 再放到邮局里面发送出去 那这个就是传输层的复用过程 那对应于分用的就是我们四个人写的信 全部收到了回信 那这些回信就全部放到我们的信箱当中 那这个信箱当中的信 我们就会取出来 然后分发给我们四个人当中的具体某一个人 那这个对应的过程 其实就类似于我们传输层的分用过程
  • 我们之前在讲网络层的时候 学过一个首部校验和 那这个校验只是校验头部 但是没有校验数据部分 那因此就需要它这个高层 ,也就是传输层来实现对于这个数据的一个检错 因为网络层的数据部分就是传输层的报文段 因此这个传输层 如果对这个报文进行了差错检测 那么网络层就不需要再对这个报文差错检测了, 也就只需要检测IP数据报的头部 而不用检查数据部分,那可以看到这个传输层和网络层加一块 就可以实现一个可靠传输的功能
  • 当然这个传输层啊并不是一定会实现一个可靠传输的 这就是因为传输层 它有两种协议 一个叫做TCP 一个叫做UDP

传输层的两个协议

在这里插入图片描述

传输层的寻址与端口

在这里插入图片描述
在这里插入图片描述

  • 分用指的是传输层从网络层收到数据后可以交付给指明的 或者是对应的应用进程,那是如何指明给具体的应用进程 我们先想在网络层和链路层,对于一个主机, 如果我们要把这个数据发送给它 我们只需要知道它的IP地址就可以了 那在这个网络当中 就只需要根据IP地址,寻找到它所在的网络 那进入它所在的网络之后 就要靠它的物理地址 也就是MAC地址,根据MAC地址,再定位到具体哪一个主机 那因此我们就找到了这个主机
  • 但是我们说。如果找到了主机 这个通信还不算结束 我们还应该找到这个主机当中的要接收这个数据的进程 那因此就要涉及到传输层的问题,也就是要指明交付,给一个具体的应用进程 那如何指明,其实在传输层 也会有这样一个概念,它和网络层的IP地址以及链路层的MAC地址一样 都可以唯一的标识一个主机 那在传输层都可以标识唯一的一个进程就叫做端口
  • 这个端口 它是传输层的SAP 也就是服务访问点 它可以唯一的标识主机当中具体的一个应用进程 那这个端口,它是一个逻辑端口 也叫做软件端口 这个要和我们讲的硬件端口区分开,比如说路由器或者交换机 它们上面的端口 直接插上去的那种端口叫做硬件端口 而这种端口,传输层的端口是我们看不见 摸不着的 所以我们叫它逻辑端口 或者是软件端口 那这个端口 我们会有一个具体的数字来标识,那对于每一个端口 我们都会有一个数字来标识它 那叫做端口号
  • 端口号 要注意 它只有本地意义 在因特网当中 不同计算机的相同端口号是没有联系的,比如说我的主机和你的主机 我们有两个不同的进程 但是可以使用相同的端口号,那如果我们两个正在使用相同的进程 也可以对应不同端口号,所以说端口号只需要在本机内,有唯一性 可以唯一标识一个进程就可以了 在不同主机之间 这个端口号是没有区分的意义的
  • 熟知端口号:指的就是给TCP/IP当中一些最重要的应用程序所标识的端口号,它是让所有用户都知道的 所以这个熟知端口号也叫做知名端口号,就是一些非常重要的程序才会固定确定好这样一个端口号 全人类都知道的
  • 登记端口号: 仅仅在客户进程运行的时候才动态选择 为什么说它动态选择,因为这个客户端使用的端口号只有在使用的时候 才会给它分配一个,而且是主机当中的操作系统给它随机分的 那这个进程只要一结束这个端口号 就可以分配给新的一个进程 所以这个端口号是可以循环利用 可以动态选择的
  • 套接字:它其实就是一个主机IP地址和端口号的组合 那看到这个大家就应该清楚,根据IP地址可以找到主机 根据端口号可以找到主机当中的具体进程,因此 我们说的套接字 它就可以唯一标识网络当中的一个主机以及它上面的一个进程,也就是说一个套接字 它是可以标识一个端点的 端点也就是我们最终通信的那个终点,也就是具体主机当中的一个具体进程

5.2.1 UDP协议

用户数据包协议UDP概述

在这里插入图片描述

  • 网络层是不可靠的交付尽最大努力交付 那传输层如果使用UDP协议的话 也不会保证可靠交付 那可靠交付由谁来保证?那就是由传输层的上一层 也就是由应用层来保证这个可靠以及顺序的交付
  • UDP是面向报文的 其实就是在说UDP对于应用层交下来的这个报文是既不合并也不会拆分的,对这个报文的长度 大小是不做任何改变的 而是保留这些报文的边界,也就是 整个应用层的报文都会放到传输层的一个报文段当中,或者说放到这个UDP的一个UDP数据报当中
  • 应用程序就一定要选择一个大小比较合适的报文,如果这个报文太长的话 我们可以想一下 当这个UDP把这个报文,完整的装进来并且交给网络层的时候 那网络层就要分片了, 因为接下来要传递给链路层的话,它有一个MTU的要求,所以到网络层这边就需要分片,那这样就给网络层的效率造成了影响 就会降低网络层的效率
  • 那我们想这个应用层的报文如果过小,如果这个报文过小的话 把它一直传到网络层,那这个IP数据报的数据部分 就相比首部来说要少很多了,也就是说会使IP数据报的首部相对长度太大 那这样也会降低网络层的效率,因为我们都希望这个首部 也就是这种附加信息尽可能的少 那一个数据报当中所含的数据部分尽可能多
  • 那综上所述 我们这个应用层所选择的报文长度就应该适当
  • 而如果使用UDP协议 就会把整个应用层报文封装到这个传输层的数据传输单元,也就是一个用户数据报 或者我们称之为报文段
  • 第三点说 UDP面向报文 它就适合一次性传输少量数据的网络应用 因为如果太大的话最后还要分片,由于UDP协议 它是不可靠的交付,所以导致数据容易丢失 那因此我们一次性也不要传输太多 这样损失可能比较大,所以UDP适合一次性传输少量数据的网络应用

UDP首部格式

在这里插入图片描述

  • 数据字段 是可以为0的 所以这一个UDP的数据报它最少可以是8字节,也就是一定会有这个首部字段
  • 端口号的长度 就是16位 因此这个端口号它可以表示的范围就是从0~65536也就是2的16次方
  • 这个源端口号 它是可有可无的 如果我发送的这个数据报 我希望收到对方的回复,那我这个源端口号我就添上 因为我添上了之后,对方才知道发给哪个进程,当然如果我不需要他给我回信的话 那我这个端口号就可以是全0的
  • 目的端口号 是一定要有的,因为我发送一个用户数据报或者说发送一个报文段一定是有指向 有目的的 究竟要发给哪个主机的哪个进程 因此 这个目的端口号是一定要有的
  • UDP长度 指的是整个用户数据报的长度 也就是首部加上数据字段
  • UDP检验和,其实是在检验整个UDP数据报是不是有出错,也就是包括首部字段以及数据字段,是不是发生错误了 如果发生差错 就会把这个UDP用户数据报给丢弃掉

UDP校验

在这里插入图片描述

  • 伪首部当中 它包括源IP地址以及目的IP地址 还有这个17,这个17啊其实就是IP数据报首部的协议字段,那这个协议字段其实就在说明数据部分使用的是什么字段,那这个里面 我们数据部分使用的是UDP协议 也就是我们传输层使用UDP协议 那传输层的UDP所对应的一个协议字段值就是17
  • 伪首部的第三个字段固定全0

在这里插入图片描述

  • 如果这个数据部分 它是8字节,或者说他每一横条都可以满足四个字节的话就不需要填充 那这里面数据部分是7字节 所以我们要再填充1个字节的全0字段,使得这个数据部分 它是四字节的整数倍
  • 伪首部只是在发送端和接收端,在校验数据报中有没有发生差错的时候才会添加的

5.3.1 TCP协议

在这里插入图片描述

  • 那之所以说面向连接 就是指,应用程序在使用这个TCP协议之前 必须要先建立好一个TCP的连接,在传送数据完毕之后 再释放这个已经建立的连接 也就是说 两个应用进程之间的通信好像就是在打call一样,只要两个人电话打通了 才可以进行数据的传输 也就是TCP它面向连接的一个特点
  • 那这里面为什么说的是虚连接,这其实跟我们之前讲传输层逻辑通信是一样的道理 它并不是实际的一个物理连接 因为实际上这个连接过程应该是把这个数据报加上,各个层次的首部之后放到链路上面传输 然后再到接收端进行一步又一步的解封装 这个是一个完整的物理连接,但是TCP协议的使用 就好像两个进程之间建立一个,一点对另一点的这种点对点的连接 好像是进程和进程直接连在一起了 所以我们说是一种虚连接
  • TCP连接只能是点对点一对一的 所以TCP协议 是没办法用于广播以及多播的这种通信方式
  • TCP协议连接的两端都会设置有发送缓存以及接收缓存 发送缓存 其实大家就可以想象成是一个准备发送的一个队列 接收缓存的就是一个准备接收的队列

在这里插入图片描述

  • 假如说发送方 他要发送这样一个文件 那他会把这个文件 按照字节给他排个序 然后编上号,这个是第一个字节 这是第二个字节 第三个字节
  • 那在发送的时候 就会把这些字节放入TCP的缓存当中 那这就是传输层 他所做的一个事情
  • 可以看到 在这个图里 是把第1个字节到第10个字节 也就是这10个字节放入缓存当中等待发送
  • 那现在如果可以开始发送,什么情况呢 可能先取的是123字节 组成一个TCP的报文段 然后在这个报文段上加上TCP的头部,TCP的头部 或者说是TCP的首部形成一个完整报文段,在放到内容上面进行一个传输 那当然后面这个字节个数是不定的 这个要取决的因素有很多 我们之后会详细讲到
  • 所以可以看到TCP 它是面向字节的 或者说面向字节流的

在这里插入图片描述

  • 那接收端TCP缓存当中 就已经存入了这个123,那既然是面向连接的 我发送一个报文段 你就应该回复我一个确认 那你回复我确认之后 我才会再去发送我的新的一个报文段
  • 接收端收到了123这样一个报文段之后 他就会返回给他一个确认报文段 那这个报文段当中的首部就会有一个字段是确认,确认号字段 那这个确认号字段应该是多少 我们刚才说确认号应该是期待对方,下一个要发送报文段的第一个字节 那我们可以看到现在已经收到了123这三个字节 接下来我希望收到是谁 应该希望收到是4号字节,如果我希望收到4号字节 那我这个确认号就标上4,就告诉发送方 接下来你可以给我发送4字节了 同时也可以告诉发送方4字节之前的123我全都已经正确接收

在这里插入图片描述

  • 假如说我们在发送文件 发送的好好的 这个接收方跟我说 我现在没有办法接受你的文件了 你赶快停止,那这个发送方收到这样一个信息之后 他就应该赶快叫停
  • 那这个发送方的叫停 一定是要输入一些命令,那这些命令的体现 其实就是又新加入了一些数据 那这些数据 就会进入到这个TCP缓存当中
  • 那我们在这个缓存当中构成首部的时候,假如说我们现在这个456构成了一个TCP报文段,789又构成了一个报文段,那这个10 他可能自己变成了一个报文段,那接下来11 12 13这个紧急的数据 它也形成了一个报文段
  • 11 12 13生成报文段的时候 他的首部字节里面 他首部里 首部URG里面 URG现在就等于1,如果URG等于1 就说明这是一个紧急的数据,紧急的报文段就应该赶紧发送而不应该在TCP缓存当中排队,所以 URG等于1就赋予了这个报文段一个插队的权利,那这个报文段就可以移到最前面,走到最前面 赶紧发送出去,所以这个就是URG等于1的时候 报文段就有一个优先级,他就可以先从TCP缓存当中赶快发出去 而不用等到排队排到他这儿再发送

TCP报文段首部格式

在这里插入图片描述

  • 那为什么要赋予这个填充字段 就是因为这个TCP 他有强迫症 他希望字节的这个首部,它是四字节的整数倍,也就是4n字节 所以说为了使这个添加选项之后还是保证4字节的整数倍 就要往上面填充一些东西,这个是填充字段的作用 那填充的话 我们经常填充的都是全0字段
  • 因为我们知道,有的时候 这个TCP报文段并不一定是一个20字节的固定首部 有可能他加了一定的这个选项字段,加了选项和填充字段 因此只要加了这个长度可变的字段 我们就不是很清楚这个数据部分是从哪开始的,所以 就应该有这样一个字段,即数据偏移, 来规定一下这个首部是多长 就知道这个数据部分应该是从哪里开始了

在这里插入图片描述
在这里插入图片描述

  • 窗口指的并不是自己的发送窗口 而指的应该是自己的一个接收窗口,假如说a现在要给b发送数据 那b在发送一个报文的时候 这个报文的窗口字段,这个窗口字段 其实就反映了自己可以容纳的 最多的字节流,或者说可以容纳的这个数据量是多少 那把这个信息发给a了 a就知道我应该如何设置我的这个发送窗口,或者说是这个发送缓存 根据这个接收方的窗口大小 我来设置我的发送缓存
  • 假如说b给a发送的这个窗口 大小是65536,那这个a收到之后 就把自己的这个发送缓存设置为65536 因为我们想如果这个再大的话,首先 这个65536已经到了这个窗口的大小极限了 再一个 如果这个再大一点的话,会导致发送方发送的东西过多 接受方接收不过来 那这个是我们不允许的,所以我们会根据这个接收方的窗口大小,来限制字节的这个发送窗口 或者说发送缓存的大小
  • 再举一个例子 假如说现在这个b 发送了一个报文段 那这个报文段当中的确认序号,确认号是701 窗口字段是1000,那我们来分析一下 如果确认号是701 也就是说b希望a开始发送的这个字节应该是从701开始发送 也就是期待下一个字节应该是从701开始 那这个窗口 窗口指的就是,我现在的接收窗口 只能容纳1000个字节,所以b这一端的接收缓存空间 其实也就是1000字节 那这1000字节应该是从701一直到1700
  • 检验和和UDP一样 都是检验首部和数据部分,检验的时候 也是要和UDP一样加上12字节的伪首部,那这个伪首部 就是在伪IP数据报的首部 那第四个字段其实就是协议字段
  • 紧急指针 那指出的 就是紧急数据的末尾 在报文段当中的一个位置,如果这个紧急指针现在是50 那么说明这个TCP数据部分从第1个字节到第50个字节 这些都是紧急数据,剩下来的就是普通数据 就不着急的这些数据

5.3.2 TCP连接管理

TCP连接管理

在这里插入图片描述

  • 客户和服务器,虽然他们的角色不同 但是他们都可以接收数据并且发送数据

TCP的连接建立

在这里插入图片描述

  • seq其实就是上节课所讲的这个序号 序号位它是占32位 也就是占了四个字节,序号位是随机产生的 是由这个主机内部随机产生一个序号 可以从1开始 也可以从任意一个随机数开始
  • 同步位只有在两种情况下置为1 一个是连接请求 一个是连接请求的接受 或者说连接请求的确认
  • 由于刚刚在第一步当中所发送的这个连接请求报文段 他没有数据部分 因此这个序号其实标识的就是这个报文段,它是序号x,接下来 这个服务器端想要收到的下一个字节,就应该是从x+1开始,因此这个ack确认号字段就置为x+1,那同样对于 对于这样一个确认报文段他也有这个序号字节 那这个序号字节也是主机随机分配的

SYN洪泛攻击

在这里插入图片描述>* 洪泛攻击 它是由于三次握手才产生的这样一种黑客攻击问题 攻击者会发送TCP SYN,这个就是指我们在三次握手的第一个过程,第一个过程当中所发送的一个连接请求数据包 那攻击者就会发送这样一个数据包

TCP的连接释放过程

在这里插入图片描述
在这里插入图片描述

  • 为什么第二步和第三步他们的确认号是一样的?因为客户在这样一段时间内并没有发送任何数据,所以他们所期待的下一个报文段 第一个字节一定都是相同的
  • 那这个seq就是w 那这个也取决于在第二步之后,也就是回复确认之后 服务器端所发送的数据量的多少
  • 第四步 也就是主机客户端 他收到了来自这个服务器端的连接释放报文段,那接下来他就要回复一个确认 也就是回复一个确认报文段,回复确认报文段之后就算是连接结束吗?当然不是 要等到一个时间 也就是等待一个计时器设置的2MSL,2MSL之后才可以算是连接彻底关闭 那这个MSL指的是最长报文段的寿命 为什么要等待这个?
  • 主要原因是这样的 如果这个客户端所发送的这样一个确认报文段,这个确认报文段没有到达服务器端丢失了 那么这个服务器端就会收不到,收不到这样一个确认 他就会重传第三个这个报文段 也就是连接释放的报文段 那么A就会在两个最长报文段寿命之内,收到这个重传的第三个报文段 重传的这个服务器的连接释放报文段 那接下来 这个主机 也就是这个客户端 就能够在这个2MSL时间内收到这样一个重传的报文段,那接下来 A会重传一次确认 并且重新启动2MSL计时器 最后如果报文段没有发生丢失 A和B都会正常的进入到这个关闭的状态 连接就算结束了
  • 那如果这个A不等待这样一个2MSL的时间 而是在发送完这样一个确认报文之后直接释放连接 那么如果这个报文段丢失了,A就一直收不到B重传的第三个报文段 如果收不到的话 B就会一直发这个第三个报文段,B就没有办法进入这个正常的关闭状态

5.3.3 TCP可靠传输

TCP可靠传输

在这里插入图片描述

序号

在这里插入图片描述

  • 首先就是这个序号的机制 我们之前讲过TCP协议 它是面向字节流的 那因此我们这个TCP传输的时候 就是按照这样一个字节为单位,所以我们就会把一个字节编上一个序号 第一个字节就是序号1 第二字节序号2,以此类推
  • 那当然 对于一个文件 或者是要发送的数据 它的第一个字节 这个序号是多少是可以随机的
  • 那当然 在实际发送的时候 我们是以报文段为单位,虽然我们说TCP是面向字节流 但是在发送的时候,他就会把一些字节放在一起 组成一个报文段, 然后再把这个报文段发送出去 那这个报文段的大小也是不定的,可以是三个字节 三个字节 两个字节 两个字节 这只是比较少的情况,那也可以 多个字节 几十个字节 几百个字节 形成一个报文段都可以
  • 那这个报文段的大小划分的叫取决于链路层 它的MTU 也就是最大传输单元来决定 所以根据刚才所讲的 我们就知道一个字节 它是占用的一个序号的
  • 同时有关于序号 我们在TCP报文段格式的时候也学习过了一个序号字段,那这个序号字段指的就是一个报文段 它的第一个字节的序号 那比如说这样第一个报文123这三个字节组成的报文段,这个报文段 它首部当中的序号字段 应该就是1,填写的就是第一个发送的这个字节的序号,那有了这个序号 就可以保证数据能够有序的提交给应用层

确认

在这里插入图片描述

  • 而基于这个序号机制 我们就产生了接下来的确认以及重传机制 我们先结合一个例子来理解一下这个确认的过程
  • 首先 发送方要给接收方发送第一个报文段 也就是123字节所构成的这样一个报文段,那发过去之后 接收方就收到了 并且存储在自己这个TCP的缓存当中 然后再找一个合适的时间,把这个缓存当中的数据 或者说把缓存当中的报文段上传上去 提交给应用层
  • 那可以看到 现在这个发送方TCP缓存当中还是有123字节组成的报文段,这是为什么?因为我们知道 如果这个网络太过于复杂的话,或者说 网络上面出现了一些问题 有可能就导致这个TCP报文段发生了丢失现象 也就是这个第一个报文段123字节,他们在传输的过程当中丢失了 那因此 接收方就收不到这样一个报文段,所以接收方 他可能就会让这个发送方再重新传一次,因为接收方 他为了要保证可靠传输 就应该使得发送方发送的所有数据 他都能够按序的完整的接收到,所以这个发送方就要一直保持着这样一个报文段 直到接收方告诉他 我确定收到了,然后发送方才可以把这个报文段摘除掉 或者是从缓存当中删去
  • 那这个发送方如何知道接收方正确的而且是完整的接收到了这个报文段 ?就是靠我们这个确认机制,接收方收到了这个报文段之后 就会返回一个确认报文段 那这个报文段 是在合适的时候发生的确认,我们通常使用的是一种累计确认的方式 那这个接收方可以在合适的时候发送这样一个只是起到确认作用的确认报文段,就是告诉发送方我已经收到了你的这个报文段了, 当然 有的时候这个接收方也可以在自己有数据要发送的时候 把这个确认信息捎带上 也就是我们常说的捎带确认,那这两种方式 其实都是可以实现对于发送方已发送的报文段一个确认的功能
  • 那这个接收方 假如他发送的就是一个只有确认功能的报文段 那这个报文段的首部 确认号字段就是4,因为他现已经收到了123字节 接下来他希望收到的是从4字节开始的报文段 确认号字段的就是,期待收到的下一个字节 也就是第4个字节
  • 那这个发送方一旦收到了这样一个确认报文段之后,他就知道123字节的这个报文段 接收方已经正确接收了 他就可以从TCP缓存当中把这个123字节的报文段删去,那接下来这个发送方继续发送 他发送456以及78这两个报文段
  • 可惜的是 这个456报文段 它可能是由于路由选择的一些问题 或者说是网络情况确实不太好,他就迟迟没有到达接收方 那这个接收方现在只收到了这个78的报文段,那这个时候 接收方应该如何使用确认机制来实现可靠传输?它应该使用的就是一种累计确认的方法
  • 那这个累计确认指的就是TCP只确认 这个数据流当中自第一个丢失字节为止的这样一个字节 也就是 虽然我们现在收到了78字节的报文段 但是由于456还没有到 所以这个接收方他返回的这个确认报文,这个报文段当中的首部部分确认号字段还是填的是4,也就是78这个报文段 他还会正常的接收 不过他还是会一直告诉发送方我现在需要你的这个以4字节开头的这样一个报文段,请你赶紧发送过来 所以说 他在返回这样一个确认报文段的时候 报文段的首部确认号字段仍然填的是4
  • 那因此 这个发送方一旦收到了这样一个确认号字段 他就会判定我现在这个456还没有按序到达,所以 我应该把456再继续重传一下 也就是重新发送一下456,如果现在接收方收到了456 他就会发现自己的缓存当中已经有45678了,所以那接下来他要返回的一个确认报文 首部字段当中的确认号字段就应该添的是9
  • 如果报文段是按序而且是完整到达的 那接收方 就会返回这个确认,来指导发送方接下来应该发送哪一个报文段 那如果并没有按序到达接收方 那接收方就会返回一个确认报文段,那这个报文段 就可以指示这个发送方应该重传哪一个报文段 那接下来我们就来学习下重传的机制

重传

在这里插入图片描述

  • 重传时间的规定 就相对来说要复杂一些,因为我们知道 由于TCP的下层是一个互联网的环境 那发送的报文段可能是只经过了一个高速率的局域网 ,当然也可能经过的是很多个低速率的网络,而且每一个IP数据报它所选择的路由也都是各不相同的 这会取决于当时的一个网络情况 所以就会导致对于一个发送方 他所发送的很多个报文段所走的路径不一样 所花费的时间也不一样
  • 那我们可以想一下 如果把这个重传时间设置的过短的话 就会引起很多报文段不必要的重传 因为可能有的报文段,他所传的时间比较长 有的报文段传的时间比较短 那时间设置的过短,就会导致那些传播时间过长的报文段还没有到接收方 就要再重新传一次,那这样就会使得网络负荷大大的增大
  • 那如果把这个重传时间设置的过长 那么又会使网络的空闲时间增大 降低了传输效率
  • 那么这个传输层它所所设置的重传时间究竟应该是多大? 或者说传输层它的超时计时器的这个时间应该设置为多少?
  • 那TCP协议 他采用了一种自适应的算法来动态的改变重传时间,那这个重传时间 我们叫它为RTTs,RTT我们知道是一个往返的时间 那加上s之后 s代表的就是smooth 也就是光滑 平滑的意思
  • 我们在发送第一个报文段的时候 那这个RTTs就是取的第一个报文的RTT,那这个第一个报文段RTT是从他发送开始直到收到他的确认为止,这样一段往返的时间,那接下来我们再发送第二个报文段的时候,他同样也有一个RTT 那接下来 就会根据第一个和第二个的RTT算出一个RTTs就作为现在的重传时间 那接下来,第三个报文段在发送的时候 那第三个报文段他也有一个RTT 那接下来就把第一个 第二个 第三个报文段放在一块 通过一个公式来计算一下这三个报文段 他们的一个加权平均往返时间RTTs,那以此类推 可以看到这个RTTs 它是取决于我们所发送报文段,而且是每一个报文段的RTT的 那这样一种自适应的算法就可以很好的照顾到所有的报文段,使得这个超时重传的时间并不过长 也并不过短

在这里插入图片描述

  • 假如说现在发送方已经发送了12345 一共是五个报文段 那这五个报文段 他们字节大小也可以是不同的,那首先接收方 他收到了1就是第一个报文段 他就会返回一个 对于第一个报文段的确认,那这个确认报文段当中的首部 就会有这样一个确认号字段,确认号字段 应该就设置为第二个报文段的第一个字节 也就是期待收到的下一个字节
  • 那接下来 接收方继续接收,他收到了3也就是收到了第三个报文段,但是 他仍然要返回给对于1号报文段的确认,因此 这个确认报文段当中确认号字段还是2,所以我们可以看到 如果发生了失序接收的情况 那我们所要返回的确认还是按照失序前来发送这个确认报文段,确认号设置为2
  • 接下来接收方收到了4 那可以看到现在接收方 还是没有收到2 他仍然要返回给一个对于1号报文段的确认
  • 他接下来 接收方收到了5,还是没有收到2 那接收方比较固执 他仍然是想要收到这个2号报文段,因为他要保证一个可靠传输 所以 他还是要返回给1号报文段的一个确认
  • 那虽然现在是有四个确认报文段,但是后面三个 是三个冗余的确认报文段,那因此 发送方如果收到了三个冗余的ACK 也就是收到了三个对于报文段1的冗余确认报文段之后,就会判定自己已发送的这个2号报文段发生了丢失的情况 因此他就会重传2号报文段,那这种技术 通常称之为快速重传技术
  • 这里面要补充的一点就是,在学习TCP的时候 正常情况下 我们是应该来学习TCP协议当中的这个发送缓存 发送窗口 接收缓存 接收窗口,而且还要学习这个TCP协议 他在发送过程当中使用的一些协议,比如说停等协议 GBN协议 还有SR协议 那这些协议以及这个窗口的概念 我们在链路层的时候已经讲过了 那这两个层次他们所使用的这些协议在使用过程当中 其实是大同小异的,基本上原理是差不多的
  • 所以我们可以看到 在这个例子当中 发送方他可以连续发送好几个报文段,而不用非要等到这个1号报文段的1号确认到了之后再发送这个2号报文段 也就是TCP它是不常使用停等协议的,它可以使用GBN协议或者是SR协议 一次性可以发送多个报文段 然后接收方可以使用累计确认

5.3.4 TCP流量控制

TCP流量控制

在这里插入图片描述

  • 拥塞 简单来说其实就是网络堵塞了,那么 也就是说明在这个网络当中 使用网络带宽 网络资源的主机太多 所以才会导致整个网络出现了一个,发送缓慢 或者说转发缓慢 以及排队时延过长的这样一个问题 那这就是资源的拥塞情况,我们说发送方的发送窗口 就要取决于接收窗口以及拥塞窗口这两个值的最小值
    在这里插入图片描述
  • 在这个例子当中 我们可以注意到接收方的主机B 它进行了三次的流量控制 第一次它把这个窗口减小到了300,第二次又减小到了100,第三次又减小到0 也就是不允许主机再发送数据了
  • 那这种状态一直到什么时候才可以有所改变 或者说到什么时候主机A才可以继续给B发送数据,这种状态是一直持续到主机B重新发出一个新的窗口值为止,也就说B主机 它在这个接收缓存当中腾出了一些地方,把这个缓存当中的一些数据上交给了上层的应用层进行处理之后 才可以允许主机A继续给它发送数据,那这个时候 主机B就会给主机A发送一个接收窗口为400的一个报文段,也就是告诉主机A 现在你可以把你的发送窗口设置为400了,也就是相当于告诉主机A你可以继续发送数据
  • 但是现在出现了一个状况 这个报文段 也就是主机B返回的这样一个报文段 在发送的过程当中丢失了,么A 它就会一直处于一个等待的状态 一直等待B发来一个非0窗口的通知,A就一直待命 希望主机B能告诉它可以发送数据
  • 然而 B也一直等待这个A所发送的数据 因为B它已经发送了一个通知,那如果没有其它措施的话 主机A和主机B就会一直相互等待 那这种相互等待的情况 就很类似于操作系统当中的死锁局面,那这种死锁就会一直的延续下去
  • 那我们就想有没有一种办法来解决这个问题 当然是有的 我们采取的办法就是,TCP会为每一个连接都设有一个持续的计时器 那只要TCP连接的一方收到对方的零窗口通知之后,就会启动一个持续计时器 也就是说 主机A现在收到了一个接收窗口为零的,也就是告诉它你先不要发送数据的这样一个通知 之后 它就会设置好一个持续计时器
  • 如果这个计时器设置的时间到期了 主机A或者说发送方就会发送一个零窗口的探测报文段,那这个报文段是只携带了1字节的数据,那接收方只要收到这样一个探测报文段的时候 就会再次给出自己的这样一个现在的窗口值,就是说 主机B 即使它发送了一个通知丢失了 但是由于主机A它设置了一个持续计时器,这个计时器到期之后 主机就会发送一个探测报文段 那主机B相当于会重传一次这个通知
  • 如果主机B发送了一个通知 窗口字段仍然是0的话,也就是说 仍然不允许主机A发送数据 那主机A就会从收到这样一个通知之后再重新设置一个持续计时器

5.3.5 TCP拥塞控制

TCP拥塞控制

在这里插入图片描述
拥塞控制和流量控制的区别?

  • 首先可以看到第一个图,假如说这一边是一个接收方 那这几个地方 都是发送方,这些发送方的都要给这样一个接收方发送数据 那如果它们同时使用这个网络上的资源 或者说同时使用这个节点 这个交换节点 这个路由器的话,就会使得这个网络非常的繁忙,甚至出现一个拥塞的情况,那么这个接收方 就会察觉到这样一种拥塞情况 但是它却并不知道,这种拥塞情况究竟是具体哪一台主机 或者是哪几台主机发送速率过快 或者说发送数据过多所造成的
  • 流量控制 它是一种点对点之间的通信量的控制 是一个端到端的问题,如果这个接收方它收来的这个数据来不及接收了 那它知道应该找谁 找的就是这个发送方
  • 所以说流量控制 它是一个点到点之间的一个问题,而拥塞控制 它是一个全局性的问题
  • 再有一点 就是拥塞控制 主要是因为这个网络发生了堵塞,导致很多发送方发送来的数据 迟迟到不了接收方
  • 而这个流量控制 就是这个发送方的速率过快,导致这个接收方它接收缓存不够 或者说它的接收窗口不够,也就是来不及接收 那这就是拥塞控制和流量控制的一个区别

拥塞控制四种算法

在这里插入图片描述

慢开始和拥塞避免

在这里插入图片描述

  • 拥塞窗口最开始的初始值 是默认设置为1的 也就是cwnd等于1 那这个1代表的并不是一个字节,我们为了讨论方便 在这里面1指的就是一个报文段 而这一个报文段 它的长度是一个最大报文段的长度MSS
  • 新的门限值是什么时候确定的》就是在网络拥塞的情况下马上确定的,只要发生了网络拥塞 立刻把当时的拥塞窗口除以2定义为新的门限值 也就是把24÷2定义为新的门限值12,所以说 之后如果再撞到这个12了 我们马上就要采取这个拥塞避免的加法增大过程
  • 至于这个拥塞窗口 它什么时候翻倍 也就是在慢开始的时候 它什么时候由4变成8 由2变成4 由1变成2的,这个是只要收到了之前所发送的报文的确认,一收到确认 马上就会把这个拥塞窗口翻倍,然后再去发送这个报文段

快重传和快恢复

在这里插入图片描述

  • 那为什么叫做快恢复 就是说不用降到1,直接降到新的门限值这 然后使用拥塞避免的算法

总结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值