当前位置:   article > 正文

网络通信-滑动窗口协议-SWP

滑动窗口协议

本篇主要讲解:网络通信-滑动窗口协议-SWP
参考链接1
参考链接2
参考链接3


目录

网络通信-滑动窗口协议-SWP

TCP可靠传输

TCP可靠传输的实现,依赖如下机制

  • 序列号

TCP中将要发送的数据包的每个字节都分配序列号,用来唯一标识每个字节

  • 确认应答

当接收方收到一个数据包后,会返回一个ACK确认包,或者延迟一段时间返回一个ACK确认包,一次性确认多个数据包。

  • 自动重传

ARQ - Auto Repeat reQuest,即自动重传请求, 当TCP发送端发送了一个数据包的时候,会设置一个定时器,如果在定时器期间没有收到接收方对这个数据包的ACK确认应答包,就会重新发送对应的TCP数据包。

  • 滑动窗口协议 (Sliding Window Protocol)

早期的网络通信中,通信双方不会考虑网络的 拥挤情况直接发送数据。由于大家不知道网络拥塞状况,同时发送数据,导致中间节点阻塞掉包, 谁也发不了数据,所以就有了滑动窗口机制来解决此问题
TCP 中采用滑动窗口来进行传输控制,滑动窗口的大小(下文叙述)意味着接收方还有多大的缓冲区可以用于接收数据。发送方可以通过滑动窗口的大小来确定可以发送多少字节的数据

窗口介绍

链路层 ,操作系统开辟的一块 循环使用的内存缓冲区,以字节为单位并分配序号 ,发送方的应用进程把字节流写入TCP的发送缓存,接收方的应用进程从TCP的接收缓存中读取字节流。窗口实际上就是缓冲区上面的一块连续的区间TCP的通信是全双工通信,通信中的每一方都在发送和接收报文段,因此每一方都有发送窗口和接收窗口发送窗口和接收窗口的序号的上下界不一定要一样,大小也可以不同

窗口和缓存的关系

操作系统开辟的缓存空间是有限的,并且都是循环使用的 ,最好是把它们画成圆环状的,但这里为了画图的方便,我们还是把它们画成长条状的(图1)。实际上缓存或窗口中的字节数是非常之大的,这里是个示意图,所以没有标出具体的数值。

图1
[ 图1 ]

  • 发送缓存

应用层会将发送的数据写入到发送缓冲区中,当写入的数据超过发送缓冲区的最大地址后,就从头部开始循环利用,覆盖头部的数据
发送应用程序必须控制写入缓存的速率,不能太快,否则发送缓存就会没有存放数据的空间。(这个会在传输层调用send()的时候收到返回值的反馈,告之发送缓冲区的状态)

  • 接收缓存

接收的数据写入到接收缓冲区中,当接收的数据超过接收缓冲区的最大地址后,就从头部开始循环利用,覆盖头部的数据
如果接收应用程序来不及读取收到的数据,接收缓存最终就会被填满,使得接收窗口减小到0(此时发送方会根据接收方返回的窗口可用大小,停止发送)。反之,如果接收应用程序能够及时从接收缓存中读取收到的数据,接收窗口就可以增大,但最大不能超过接收缓存的大小。

  • 发送窗口

通常发送窗口只是发送缓存的一部分,发送窗口利用三个指针来维护相关的区域。(下文详述)
发送方在没有收到接收方返回ACK确认包的情况下,发送方可以连续把窗口内的数据都发送出去。
凡是已经发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用。
发送方收到接收方的ACK确认包后,根据确认包中的ACK序号和WIN窗口大小,通过调整指针实现窗口的位置调整。

  • 接收窗口

通常接收窗口只是接收缓存的一部分,接收窗口利用两个指针来维护相关的区域。(下文详述)
接收窗口中的字节序列号都是与发送窗口一一对应的,将接收到的数据按序号存放。
应用层读取数据后,从接收缓冲区中移除已经读取的数据,不过并不会真正移除数据,只需要移动对应的指针就可以了,即移动“下一个期望收到的字节(确认号)”,这个字节确认号就是接收方返回给发送方的ACK序号。

功能作用
  • 支持流量控制/拥塞控制(flow control)

它是一种接收方能够控制发送方发送速度的反馈机制这种机制用于抑制发送方发送速度过快,即抑制发送方发送的数据量,不能超过接收方所能处理的数据量。 如果发送方收到接收方的窗口大小为0的ACK,那么发送方将停止发送数据,等到接收方发送窗口大小不为0的数据报的到来。 这通常通过扩展滑动窗口协议完成,使接收方不仅确认收到的帧,而且通知发送方它还可接收多少帧(可接收的帧数对应着接收方空闲的缓冲区数)。在按序传递的情况下,在将流量控制并入滑动窗口协议之前,我们应该确信流量控制在链路层是必要的。

  • 用于保持帧的传输顺序

这在接收方比较容易实现,因为每个帧有一个序号,接收方要保证已经向上层协议传递了所有序号比当前帧小的帧,才向上传送当前帧

  • 可靠传输(核心功能)

假设发送方的发送窗口内所有的数据都已正确到达接收方接收窗口,接收方也早已发出了确认,但是所有这些确认都滞留在网络中。在没有收到接收方的确认时,发送方不能猜测:“或许接收方收到了吧!”。为了保证可靠传输,发送方只能认为接收方还没有收到这些数据。于是, 发送方在经过一段时间后(由超时计时器控制),就发送一个零窗口探测报文段(仅携带1字节的数据),而接收方就在确认这个探测报文段时给出现在的窗口值。发送方收到返回报文的窗口值有值,就自动重传这部分数据,重新设置超时计时器,如此反复,直到收到B的确认为止(避免发送方接收方互相等待,形成死锁) ,多次之后都都没有回复确认,可以直接 RST ( 在 TCP 连接发生异常情况时可以通过发送 RST 包告知对方关闭连接,直接丢弃缓冲区的包发送 RST 包)。

窗口大小

SWS: 发送窗口大小(send window size)
RWS: 接收窗口大小(receive window size)

  • 发送方的SWS的初始大小是根据链路带宽来决定的 ;在给定延迟与带宽的乘积的条件下,SWS是容易计算的。
  • 在后续的收发过程中,发送方根据接收方返回的窗口大小(即TCP数据包头部的窗口WIN值)调整构造自己的发送窗口大小 ,一般保持和接收方一致。当链路变好或者变差(拥塞变化),这个窗口大小还会动态变化
  • 接收方的RWS可以设置为任何想要的值。通常的两种设置是:RWS = 1,表示接收方不存储任何错序到达的帧; RWS = SWS,表示接收方能够缓存发送方传输的任何帧。由于错序到达的帧的数目不可能超过SWS个,所以设置RWS > SWS没有意义;

即: 滑动窗口的大小,根据链路的带宽的大小、链路拥塞情况、接收方处理数据速度,三个元素共同决定(动态)

  • 如下图示例( 图2

在这里插入图片描述
[ 图2 ]

  • 图2 )描述

发送方连续发送三次数据,每次1字节,告知发送窗口大小为3,接收方接收后回复ACK确认包,告知接收窗口为2,并通过ACK序号告诉发送方下一个应发送序号3的数据(因为接收窗口大小为2,一次确认最多接收2个字节数据);
发送方收到ACK确认包,调整窗口大小为2,重新从序号3开始发送数据,接收方接收到数据回复ACK确认包。( 发送方收到接收方窗口大小为2,调整发送方自己的发送窗口大小为2

工作原理
  • TCP的滑动窗口是以字节为单位的。为了便于说明滑动窗口的工作原理,我们把后面图示中的字节编号都取得很小

图3 )现假定A收到了B发来的确认报文段,其中窗口是20字节,而确认号是31(这表明B期望收到的下一个序号是31,而序号30为止的数据已经收到了)。根据这两个数据,A就构造出自己的发送窗口,大小20

图3 )从发送方来看,发送方A的发送窗口表示: 在没有收到B的确认的情况下,A可以连续把窗口内的数据都发送出去。凡是已经发送过的数据,在未收到确认之前都必须暂时保留,以便在超时重传时使用

在这里插入图片描述
[ 图3 ]

图3发送窗口里面的序号表示允许发送的字节的序号显然,窗口越大,发送方就可以在收到对方确认之前连续发送更多的数据,因而可能获得更高的传输效率 。接收方会把自己的接收窗口数值放在窗口字段中发送给对方。

图3发送窗口后沿的后面部分序号表示己发送且己收到了确认 ,这些数据显然不需要再保留了。 而发送窗口前沿的前面部分表示不允许发送的序号部分 ,因为接收方都没有为这部分数据准备临时存放的缓存空间。

图3发送窗口的位置由窗口前沿和后沿的位置共同确定
发送窗口后沿的变化情况有两种可能,即不动(没有收到新的确认)和前移(收到了新的确认) 。发送窗口后沿不可能向后移动,因为不能撤销掉已收到的确认。

发送窗口前沿通常是不断向前移动,但也有可能不动 (这对应于两种情况:一是没有收到新的确认,对方通知的窗口大小也不变;二是收到了新的确认但对方通知的窗口缩小了,使得发送窗口前沿正好不动)。

但是发送窗口前沿也有可能向后收缩。这发生在对方通知的窗口缩小了。但TCP的标准强烈不赞成这样做。因为很可能发送方在收到这个通知以前已经发送了窗口中的许多数据,现在又要收缩窗口,不让发送这些数据,这样就会产生一些错误。

图4发送窗口描述:现在假定A发送了序号为31-41的数据。这时, A发送窗口位置并未改变,发送窗口内靠后面有11个字节(31-41)表示己发送但未收到确认。而发送窗口内靠前面的9个字节(42-50)是允许发送但尚未发送的

在这里插入图片描述
[ 图4 ]

从( 图4 )可以看出,要描述一个发送窗口的状态需要三个指针:P1,P2,P3。指针都指向字节的序号。这三个指针指向的几个部分的意义如下:

  • 小于P1的是已发送并已收到确认的部分
  • 大于P3的是不允许发送的部分
  • P3-P1=A的发送窗口
  • P2-P1=己发送但尚未收到确认的字节数
  • P3-P2=允许发送但当前尚未发送的字节数(理解为可用或有效窗口)

图4接收窗口描述:B的接收窗口大小是20,在接收窗口后面,到30号为止的数据,是已经发送过确认并且己经交付主机的数据,因此在B可以不再保留这些数据。 接收窗口内的序号(31~50)是允许接收的空间(等待接收数据),但是B只收到了序号为32和33的数据,这些数据没有按序到达,序号为31的数据没有收到(也许丢失了,也许滞留在网络中的某处)。请注意,接收方B只能对按序收到的数据中的最高序号给出确认因此接收方B返回发送的确认报文段中的确认号仍然是31(即期望收到的序号),而不能是32或33

图5接收窗口描述现在假定B收到了序号为31的数据,并把序号为31~33的数据交付主机,然后B删除这些数据。接着把接收窗口向前移动3个序号,同时给A发送确认,其中窗口值仍为20,但确认号是34。这表明B已经收到了到序号33为止的数据。 我们注意到,B还收到了序号为37,38,40的数据,但这些都没有按序到达,只能先暂存在接收窗口中,等待缺少的数据到达(选择重传协议,在下方补充描述)

在这里插入图片描述[ 图5 ]

图5发送窗口描述A收到B的确认后,就可以把发送窗口向前滑动3个序号,但指针P2不动。可以看出,现在A的可用窗口增大了,可发送的序号范围是42~53

图6 )A在继续发送完序号42~53的数据后, 指针P2向前移动和P3重合。发送窗口内的序号都已用完,但还没有收到接收方的确认。由于A的发送窗口已满,可用窗口已减小到零,因此必须停止发送根据可靠传输的特性(在功能作用中描述),等待接收方返回确认,如果A收到确认号落在发送窗口内,那么A就可以使发送窗口继续向前滑动,并发送新的数据

在这里插入图片描述[ 图6 ]

  • 注意事项

TCP要求接收方必须有累积确认的功能,这样可以减小传输开销 。接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息顺便梢带上。但请注意两点。
1、接收方不应过分推迟发送确认,否则会导致发送方不必要的重传,这反而浪费了网络的资源。TCP标准规定,确认推迟的时间不应超过0.5秒。若收到一连申具有最大长度的报文段,则必须每隔一个报文段就发送一个确认
2、梢带确认实际上并不经常发生,因为大多数应用程序很少同时在两个方向上发送数据。

滑动窗口三种协议

基于滑动窗口,衍生出 1比特滑动窗口、 后退n、选择重传 三种协议,从窗口的观点来看,它们的差别仅在于各自窗口尺寸的大小不同而已。

  • 1比特滑动窗口协议:发送窗口=1,接收窗口=1
  • 后退n协议:发窗口>1,接收窗口>1
  • 选择重传协议:发送窗口>1,接收窗口>1
1比特滑动窗口
  • 介绍

当发送窗口和接收窗口的大小固定为1字节时,滑动窗口协议退化为停等协议(stop-and-wait)。
该协议规定发送方每发送一帧后就要停下来,等待接收方已正确接收的确认返回后才能继续发送下一帧。接收方根据帧的序号,判断接收到的帧是新发的帧还是重新发送的帧 。由于停等协议规定只有一帧完全发送成功后才能发送新的帧,因而只用一比特来编号就够了。所以叫1比特滑动窗口

  • 缺点

停等协议要为每一个帧进行确认后才继续发送下一帧,大大降低了信道利用率
发送方交替发送标记为“奇数”和“偶数”的数据包。 发送的确认同样为“奇数”和“偶数”。 假设已经发送了奇数分组的发送方没有收到奇数确认,而是立即发送下一个偶数分组,在此之后它可能会收到一个确认,为“下一个奇数包”。这将使发送方出现不确定因素:接收方有可能接收到这两个数据包,或者两者都没接收到。

回退n步(GBN)
  • 介绍

由于停等协议要为每一个帧进行确认后才继续发送下一帧,大大降低了信道利用率,因此又提出了后退n协议
后退n协议中,发送方在发完一个数据帧后,不停下来等待应答帧,而是连续发送若干个数据帧,即使在连续发送过程中收到了接收方发来的应答帧,也可以继续发送。且发送方在每发送完一个数据帧时都要设置超时定时器。只要在所设置的超时时间内仍收到确认帧,就要重发相应的数据帧
如:当发送方发送了N个帧后,若发现该N帧的前一个帧在计时器超时后仍未返回其确认信息,则该帧被判为出错或丢失,此时发送方就不得不重新发送出错帧及其后的N帧。( 图7

在这里插入图片描述
[ 图7 ]

  • 缺点

不难看出,后退n协议一方面因连续发送数据帧而提高了效率。但另一方面,在重传时又必须把原来已正确传送过的数据帧进行重传(仅因这些数据帧之前有一个数据帧出了错),这种做法又使传送效率降低。由此可见,若传输信道的传输质量很差因而误码率较大时,连续测协议不一定优于停止等待协议。比如示例中的发送窗口的大小为k,接收窗口仍是1。

选择重传(SR)
  • 介绍

在后退n协议中,接收方若发现错误帧就不再接收后续的帧,即使是正确到达的帧,这显然是一种浪费。于是引出了选择重传协议
接收方发现某帧出错后,其后继续送来的正确的帧虽然不能立即递交给接收方的高层,但接收方仍可收下来,存放在一个缓冲区中,同时要求发送方重新传送出错的那一帧。一旦收到重新传来的帧后,就可以原已存于缓冲区中的其余帧一并按正确的顺序递交高层

  • 缺点

要求接收方有足够大的缓冲区空间

三种滑动窗口衍生协议对比
  • 如下( 图8

在这里插入图片描述[ 图8 ]

滑动窗口工作流程

上面都是以一帧一帧作为讲解,实际TCP通信中,是以数据包的长度累积作为判断的,最后结合TCP通信来看完整的滑动窗口的工作流程图9

在这里插入图片描述
[ 图9 ]

上图步骤分析

mss:Maximum Segment Size,最大报文长度
win:滑动窗口的可用窗口部分(滑动窗口剩余空间)

  • 第1次,客户端向服务器发起连接,客户端的滑动窗口可用是 4096 ,一次发送的最大数据量是 1460(一次握手)
  • 第2次,服务器接收连接情况,告诉客户端服务器的窗口可用大小是 6144 ,一次发送的最大数据量 1024(取较小值1024作为最大MSS)(二次握手)
  • 第3次,(三次握手)
  • 第4-9次,客户端连续给服务器发送了6次数据,每次发送 1k(根据第二步判断出的MSS)滑动窗口连续发送功能,期间接收方一直有累积确认回复客户端,图中未画出忽略不计,不然客户端发到 4K 数据,就会因为发送窗口数据发送完全但没有收到确认而停止发送
  • 第10次,服务器告诉客户端:发送的 6k 数据已经接收到,存储在缓冲区中(ACK确认序号),缓冲区数据已经处理了 2k,窗口可用大小是 2k(窗口大小win)
  • 第11次,服务器告诉客户端:发送的 6k 数据已经接收到,存储在缓冲区中(ACK确认序号),缓冲区数据已经处理了 4k,窗口可用大小是 4k(窗口大小win)
  • 第12次,客户端给服务器发送了 1k 的数据
  • 第13次,客户端主动请求和服务器断开连接(一次挥手),并且给服务器发送了 1k 的数据
  • 第14次,服务器回复ACK 8194,含义为:同意断开连接的请求(二次挥手);告诉客户端已经接受到刚才发送的 2k 数据;当前滑动窗口可用 2k
  • 第15次,服务端缓冲区数据部分处理之后,当前服务端滑动窗口可用 4K接收方累积确认功能
  • 第16次,服务端缓冲区数据全部处理之后,当前服务端滑动窗口可用 6K接收方累积确认功能
  • 第17次,服务器端给客户端发送FIN,请求断开连接(三次挥手)
  • 第18次,客户端回复确认,同意服务器端的断开请求(四次挥手)

说明:1-3是三次握手,4-12是正常通信;第一次和第二次握手时不能带有通信数据,因为还没有建立连接,第三次握手时可以带通信数据;

滑动窗口辅助算法优化

滑动窗口是一个解决网络拥塞,流量控制的架构,这个架构还可以辅以其他算法,处理细化的场景问题,示例如下:

  • 场景问题

糊涂窗口综合症(接收端糊涂,网络上小包泛滥的原因之一)

  • 描述

TCP接收方的缓存已满,而交互式的应用进程一次只从接收缓存区中读取1字节(这样就使接收缓存空间仅腾出1字节),然后向发送方发送确认,并把窗口设置为1个字节(但发送的数据报为40字节的话),然后,发送方又发来1字节的数据,接收方发回确认,仍将窗口设置为1个字节,这样,网络效率就会很低

  • 解决方式

Nagle算法(控制TCP报文段的发送时机)

发送方将第一个数据字节发送出去,把后面到达的数据字节缓存起来 。接收方接收这个单个字节的数据包返回确认并携带接收窗口大小当发送方接收对第一个数据字符的确认后,根据接收窗口大小把发送缓存中的数据组装成一个报文段再发送出去,同时继续对随后到达的数据进行缓存。只有在收到对前一个报文段的确认之后,才继续发送下一个报文段。规定一个TCP连接最多只能有一个未被确认的未完成的小分组,在该分组的确认到达之前不能发送其它的小分组。当数据到达较快而网络速率较慢时,用这样的方法可以明显的减少所用的网络带宽。

延迟ACK

对于接收方而言, 延迟ACK可以拖延ACK发送时间,进而延迟窗口通告,在这段时间内,接收窗口有机会进一步放大

不发送小窗口通告

对于发送方而言, 不理会接收端的小窗口通告等于说不马上1发送小包,小包有时间积累成大包

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/在线问答5/article/detail/831297
推荐阅读
相关标签
  

闽ICP备14008679号