手机网站的建设价格,网店搬家,wordpress 站内信,wordpress为什么加载速度很慢文章目录 1、概述2、校验和3、序列号和确认应答机制4、重传机制4.1、介绍4.2、超时重传4.3、快速重传 5、滑动窗口协议5.1、介绍5.2、发送方的滑动窗口5.3、接收方的滑动窗口 6、流量控制7、拥塞控制7.1、介绍7.2、慢开始7.3、拥塞避免7.4、快重传和快恢复 1、概述
TCP 是面向… 文章目录 1、概述2、校验和3、序列号和确认应答机制4、重传机制4.1、介绍4.2、超时重传4.3、快速重传 5、滑动窗口协议5.1、介绍5.2、发送方的滑动窗口5.3、接收方的滑动窗口 6、流量控制7、拥塞控制7.1、介绍7.2、慢开始7.3、拥塞避免7.4、快重传和快恢复 1、概述
TCP 是面向连接的、可靠的、基于字节流的传输层通信协议处于OSI模型的第四层传输层。 那么什么是可靠传输呢可靠传输就是保证接收方收到的字节流和发送方发出的字节流是完全一样的。也就是说通过 TCP 连接传输的数据无差错、不丢失、不重复、并且按序到达。
网络层是没有可靠传输机制的尽自己最大的努力进行交付。而传输层使用 TCP 实现可靠传输TCP 保证可靠传输的机制有如下几种
校验和 Checksum序列号和确认应答机制重传机制流量控制滑动窗口协议拥塞控制
2、校验和
所谓 TCP 的校验和Checksum就是说由发送端计算待发送 TCP 报文段的校验和然后接收端对接收到的 TCP 报文段验证其校验和TCP 的校验和是一个端到端的校验和。其目的是为了发现 TCP 的首部和数据在发送端到接收端之间是否发生了变动。如果接收方检测到校验和有差错则该 TCP 报文段会被直接丢弃。
TCP 在计算校验和时需要加上一个 12 字节的伪首部。伪首部的数据是从 IP 数据报头获取的共有 12 字节包含如下信息源 IP 地址、目的 IP 地址、保留字节 (置 0)、传输层协议号 (TCP 是 6)、TCP 报文长度 (首部 数据) 3、序列号和确认应答机制
这个机制类似于问答的形式。比如在课堂上老师会问你“明白了吗”假如你没有隔一段时间没有回应或者你说不明白那么老师就会重新讲一遍。
其实计算机的确认应答机制也是一样的发送端发送信息给接收端接收端会回应一个包这个包就是应答包(ACK)而序列号则是标识发送者是谁。 4、重传机制
4.1、介绍
在错综复杂的网络并不一定能够顺利的传输报文报文存在丢失的可能性。报文丢失的可能因素有很多种包括应用故障路由设备过载或暂时的服务宕机。报文级别速度是很高的通常来说报文的丢失是暂时的因此 TCP 能够发现和恢复报文丢失显得尤为重要。
重传机制是 TCP 最基本的错误恢复功能常见的重传机制有如下
超时重传快速重传
4.2、超时重传
超时重传是最常看到的一种重传机制如在之前提及到的《【计网】什么是三次握手四次挥手》中便多次提及到了在三次握手四次挥手中若报文丢失或超时变回触发超时重传。
超时重传就是 TCP 发送方在发送报文的时候设定一个定时器如果在规定的时间内没有收到接收方发来的 ACK 确认报文发送方就会重传这个已发送的报文段。
超时重传时间我们一般用 RTORetransmission Timeout来表示RTT Round-Trip Time 往返时延就是数据从网络一端传送到另一端所需的时间也就是报文段的往返时间。
显然超时重传时间 RTO 的值应该略大于报文往返 RTT 的值 我们可以假想一下如果超时重传时间 RTO 远大于或小于 RTT会发生什么情况
RTO 远大于 RTT网络的空闲时间增大降低了网络传输效率。即如果真的丢失了等待的时间过长原本一分钟能干五碗饭在RTO远大于RTT后一分钟只能干两碗了使得两端之间的网络传输效率变差RTO 小于 RTT不必要的重传导致网络负荷增大甚至无法完成正常的网络传输。简单来说就是如果通过TCP传输一个数据包最快需要2ms但是由于RTO小于RTT假设设置RTO为1ms那么在这个数据包还未传输到接收方时便已经触发超时重传机制导致永远无法完成该次网络传输。 如果超时重传的数据又超时了该怎么办呢TCP 的策略是重传的超时间隔加倍。
也就是说每进行一次超时重传都会将下一次重传的超时时间间隔设为先前值的两倍。
超时触发重传存在的问题是超时周期可能相对较长。有没有一种机制可以减少超时重传的等待时间呢于是快速重传机制应运而生。
4.3、快速重传
快速重传Fast Retransmit机制不以时间为驱动而是以数据驱动重传。
快速重传机制的原理每当接收方收到比期望序号大的失序报文段到达时就向发送方发送一个冗余 ACK指明下一个期待字节的序号。简单来说就是接收方收到的数据包如果不是按照顺序来的不管是乱序还是丢失也会给客户端回复冗余ACK用来标记到发送到哪里的时候乱序或丢失了。
对于何时重传有这么一个阈值当冗余ACK达到3个时便会触发重传即发现三个乱序或丢失的数据包时便会触发快速重传。 注意是冗余ACK达到3个不是收到3个重复的ACK便会触发重传因为除了3个冗余ACK外还有一个是最开始的正确的ACK所以重复的ACK是4个其中冗余ACK3个有1个是正确的ACK。 举个例子发送方已经发送 1、2、3、4、5报文段
接收方收到报文段 1返回 1 的 ACK 确认报文确认号为报文段 2 的第一个字节接收方收到报文段 3仍然返回 1 的 ACK 确认报文确认号为报文段 2 的第一个字节接收方收到报文段 4仍然返回 1 的 ACK 确认报文确认号为报文段 2 的第一个字节接收方收到报文段 5仍然返回 1 的 ACK 确认报文确认号为报文段 2 的第一个字节接收方收到 3 个对于报文段 1 的冗余 ACK认为报文段 2 丢失于是重传报文段 2最后接收方收到了报文段 2此时因为报文段 3、4、5 都收到了所以返回 6 的 ACK 确认报文确认号为报文段 6 的第一个字节 5、滑动窗口协议
5.1、介绍
我们都知道 TCP 是每发送一个数据都要进行一次确认应答。当上一个数据包收到了应答了 再发送下一个。
这个模式就有点像我和你面对面聊天你一句我一句。但这种方式的缺点是效率比较低的。
如果你说完一句话我在处理其他事情没有及时回复你那你不是要干等着我做完其他事情后我回复你你才能说下一句话很显然这不现实。 所以这样的传输方式有一个缺点数据包的往返时间越长通信的效率就越低。
为解决这个问题TCP 引入了窗口这个概念。即使在往返时间较长的情况下它也不会降低网络通信的效率。
那么有了窗口就可以指定窗口大小窗口大小就是指无需等待确认应答而可以继续发送数据的最大值。
窗口的实现实际上是操作系统开辟的一个缓存空间发送方主机在等到确认应答返回之前必须在缓冲区中保留已发送的数据。如果按期收到确认应答此时数据就可以从缓存区清除。
假设窗口大小为 3 个 TCP 段那么发送方就可以「连续发送」 3 个 TCP 段并且中途若有 ACK 丢失可以通过「下一个确认应答进行确认」。 图中的 ACK 600 确认应答报文丢失也没关系因为可以通过下一个确认应答进行确认只要发送方收到了 ACK 700 确认应答就意味着 700 之前的所有数据「接收方」都收到了。这个模式就叫累计确认或者累计应答。 那么窗口大小由哪一方决定 TCP 头里有一个字段叫 Window也就是窗口大小。
这个字段是接收端告诉发送端自己还有多少缓冲区可以接收数据。于是发送端就可以根据这个接收端的处理能力来发送数据而不会导致接收端处理不过来。
所以通常窗口的大小是由接收方的窗口大小来决定的。
发送方发送的数据大小不能超过接收方的窗口大小否则接收方就无法正常接收到数据。
5.2、发送方的滑动窗口
我们先来看看发送方的窗口下图就是发送方缓存的数据根据处理的情况分成四个部分其中深蓝色方框是发送窗口紫色方框是可用窗口
#1 是已发送**并**收到 ACK确认的数据1~31 字节#2 是已发送**但**未收到 ACK确认的数据32~45 字节#3 是未发送但总大小**在接收方处理范围内**接收方还有空间46~51字节#4 是未发送但总大小**超过**接收方处理范围接收方没有空间52字节以后 在下图当发送方把数据「全部」都一下发送出去后可用窗口的大小就为 0 了表明可用窗口耗尽在没收到 ACK 确认之前是无法继续发送数据了。
在下图当收到之前发送的数据 32~36 字节的 ACK 确认应答后如果发送窗口的大小没有变化则滑动窗口往右边滑动 5 个字节因为有 5 个字节的数据被应答确认接下来 52~56 字节又变成了可用窗口那么后续也就可以发送 52~56 这 5 个字节的数据了。 那么程序是如何表示发送方的四个部分的呢 TCP 滑动窗口方案使用三个指针来跟踪在四个传输类别中的每一个类别中的字节。其中两个指针是绝对指针指特定的序列号一个是相对指针需要做偏移
SND.WND表示发送窗口的大小大小是由接收方指定的SND.UNASend Unacknoleged是一个绝对指针它指向的是已发送但未收到确认的第一个字节的序列号也就是 #2 的第一个字节。SND.NXT也是一个绝对指针它指向未发送但可发送范围的第一个字节的序列号也就是 #3 的第一个字节。可用窗口大小 SND.WND -SND.NXT - SND.UNA指向 #4 的第一个字节是个相对指针它需要 SND.UNA 指针加上 SND.WND 大小的偏移量就可以指向 #4 的第一个字节了。 5.3、接收方的滑动窗口
接下来我们看看接收方的窗口接收窗口相对简单一些根据处理的情况划分成三个部分
#1 #2 是已成功接收并确认的数据等待应用进程读取#3 是未收到数据但可以接收的数据#4 未收到数据且不可以接收的数据 其中三个接收部分使用两个指针进行划分:
RCV.WND表示接收窗口的大小它会通告给发送方。RCV.NXT是一个指针它指向期望从发送方发送来的下一个数据字节的序列号也就是 #3 的第一个字节。指向 #4 的第一个字节是个相对指针它需要 RCV.NXT 指针加上 RCV.WND 大小的偏移量就可以指向 #4 的第一个字节了。 那么接收窗口和发送窗口的大小是相等的吗 答案是并不完全相等接收窗口的大小是约等于发送窗口的大小的。
因为滑动窗口并不是一成不变的。比如当接收方的应用进程读取数据的速度非常快的话这样的话接收窗口可以很快的就空缺出来。那么新的接收窗口大小是通过 TCP 报文中的 Windows 字段来告诉发送方。那么这个传输过程是存在时延的所以接收窗口和发送窗口是约等于的关系。
6、流量控制
想象一下这个场景主机 A 一直向主机 B 发送数据不考虑主机 B 的接收能力则可能导致主机 B 的接收缓冲区满了而无法再接收数据从而导致大量的数据丢包引发重传机制。而在重传的过程中若主机 B 的接收缓冲区情况仍未好转则会将大量的时间浪费在重传数据上降低传送数据的效率。
所以引入了流量控制机制主机 B 通过告诉主机 A 自己接收缓冲区的大小来使主机 A 控制发送的数据量。总结来说所谓流量控制就是控制发送方发送速率保证接收方来得及接收。
TCP 实现流量控制主要就是通过 滑动窗口协议。
在前面说到滑动窗口的大小是由接收方告知发送方的那么是如何告知的呢在《【计网】什么是三次握手四次挥手》中其实有展示过只是未提及在数据报文中是存在这么一个16位的 窗口大小 Window 字段。
该字段的含义是指自己接收缓冲区的剩余大小于是发送端就可以根据这个接收端的处理能力来发送数据而不会导致接收端处理不过来。
因此通常来说窗口大小是由接收方来决定的。 接收方会在发送 ACK 确认应答报文时将自己的即时窗口大小接收窗口 rwnd填入并跟随 ACK 报文一起发送出去。而发送方根据接收到的 ACK 报文中的窗口大小的值改变自己的发送速度。如果接收到窗口大小的值为 0那么发送方将停止发送数据。并定期的向接收端发送窗口探测数据段提醒接收端把窗口大小告诉发送端。 7、拥塞控制
7.1、介绍
所谓拥塞就是说在某段时间对网络中某一资源的需求超过了该资源所能提供的可用部分即 需大于供)网络的性能变差。
如果网络出现拥塞TCP 报文可能会大量丢失此时就会大量触发重传机制从而导致网络拥塞程度更高严重影响传输。 其实只要「发送方」没有在规定时间内接收到 ACK 应答报文也就是触发了重传机制就会认为网络出现了拥塞。 因此当出现拥塞时应当控制发送方的速率。这一点和流量控制很像但是出发点不同。
流量控制是为了让接收方能来得及接收而拥塞控制是为了降低整个网络的拥塞程度防止过多的数据注入到网络中。
为了调节发送方所要发送数据的量定义了「拥塞窗口 cwnd」的概念。拥塞窗口是发送方维护的一个状态变量它会根据网络的拥塞程度动态变化
只要网络中出现了拥塞cwnd 就会减少;若网络中没有出现拥塞cwnd 就会增大。
在引入拥塞窗口概念之前发送窗口大小和接收窗口大小基本是相等的关系即取决于接收窗口大小。引入拥塞窗口后发送窗口的大小就等于拥塞窗口和接收窗口的最小值。
7.2、慢开始
慢开始的思路就是TCP 在刚建立连接完成后如果立即把大量数据字节注入到网络那么很有可能引起网络阻塞。好的方法是先探测一下逐步提高发送数据包的数量即由小到大逐渐增大拥塞窗口数值。cwnd 初始值为 1每经过一个传播轮次cwnd 加倍指数增长。 当然不能一直执行慢启动这里会设置一个慢启动轮限 ssthresh 状态变量
当 cwnd ssthresh 时继续使用慢启动算法当 cwnd ssthresh 时开始使用拥塞避免算法。
7.3、拥塞避免
拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢增大即每经过一个往返时间 cwnd 加 1。
注意无论是慢开始阶段还是拥塞避免只要出现了网络拥塞触发超时重传机制慢开始轮限 sshresh 和 拥塞窗口大小 cwnd 的值都会发生变化乘法减小
ssthresh 设为 cwnd/2cwnd 重置为 1
由于拥塞窗口大小重置为 1 了所以就会重新开始执行慢启动算法。 7.4、快重传和快恢复
快速重传和快速恢复算法一般同时使用。当触发快速重传机制即接收方收到三个重复的 ACK 确认的时候就会执行快重传算法触发快速重传机制和超时重传机制的情况不同TCP 认为触发快速重传的情况并不严重因为大部分没丢只丢了一小部分快速重传做的事情有
阻塞窗口减半即cwnd cwnd/2慢开始轮限 阻塞窗口即ssthresh cwnd重新进入拥塞避免阶段。
后来的 快速恢复 算法是在上述的“快速重传”算法后添加的当收到 3 个重复ACK时TCP 最后进入的不是拥塞避免阶段而是快速恢复阶段。
快速恢复的思想是数据包守恒原则即同一个时刻在网络中的数据包数量是恒定的只有当旧数据包离开了网络后才能向网络中发送一个新数据包如果发送方收到一个重复的 ACK那么根据 TCP 的 ACK 机制就表明有一个数据包离开了网络于是 cwnd 加 1。如果能够严格按照该原则那么网络中很少会发生拥塞事实上拥塞控制的目的也就在修正违反该原则的地方。
具体来说快速恢复的主要步骤
把 cwnd 设置为 ssthresh 的值加 3然后重传丢失的报文段加 3 的原因是因为收到 3 个重复的 ACK表明有 3 个旧数据包离开了网络再收到重复的 ACK 时拥塞窗口 cwnd 增加 1当收到新的数据包的 ACK 时把 cwnd 设置为第一步中的 ssthresh 的值。原因是因为该 ACK 确认了新的数据说明从重复 ACK 时的数据都已收到该恢复过程已经结束可以回到恢复之前的状态了也即再次进入拥塞避免状态。