zoukankan      html  css  js  c++  java
  • 可靠数据传输基本原理(3)-滑动窗口

    前两篇文章分别解释了可靠性传输要解决的两件事情:

    1:数据受损怎么办

    2:数据丢失怎么办

    可靠性传输核心解决办法:

    1:停等协议(等前一个彻底确认发送成功后再发送下一组数据)

    2:重传(如果传输受损,重传;如果传输丢失,重传)

    通过以上两个方法外加序列号,校验等已经实现了可靠性传输。但是有性能问题

    停等协议的弊端

    信道利用率U=传输时间 /传输时间 + RTT。当RTT很大是,传输效率会非常低下。

    把信道假设为一条高速公路,停等类似于前一辆车到达终点后下一辆车才能开始进入高速公路,效率可想而知。

    引入流水线

    不再以停等的形式进行发送,而是一次传输多个,下图为例,一次性传输三组数据使得信道的利用率提高了三倍。

     同样用高速公路作为例子,车子一辆跟着一辆进入高速公路。

    停等和流水线运行时状态

     

    流水线需要面对的问题

    1. 更多的序号,停等0,1就够了。

    2.发送的过程中可能会乱序,发送方最低限度需要缓存已经发送但是没有确认的数据分组,接收方也许也要缓存已经收到的数据。

    滑动窗口基本模型

    下图为一个基本的滑动窗口在发送端的模型

    说明

    • 窗口大小为N(窗口的大小在TCP中是在握手的阶段接收方告诉发送方的,后续随着网络情况和接收方读取的速度,会实时进行调整),最大为65535字节。
    • Base下一个等待确认的序号。
    • NextSeqNum为下一个即将要发送的序号。

    行为

    • 发送方缓存了已经发送但是没有确认的数据分组(因为如果超时没有确认,需要重新传递这些数据)
    • 当Base对应的序号确认后,窗口向右滑动一格,同时把序号为NextSeqNum对应的数据分组发送出去:Base=Base+1,NextSeqNum=NextSeqNum+1.

    滑动窗口之回退N步-GNB(Go-Back-To-N)

    • 累计确认:收到一个序号为n的ack,代表接收方已经收到了序号为n以及n以前的全部分组
    • 超时,如果发生超时,发送方重新传递所有已经发送但是还未确认的分组
    • 接收方丢弃所有失序的分组,如果接收方期待的是N,如果N+1到了,则直接丢弃。

    示意图

    GBN的好处就是简单,接收方只需要维护一个期待的序列号即可。

    最大的问题是资源浪费,上图可以看出即使分组3,4,5被正确接受了,但是因为分组2丢失了,导致2,3,4,5被全部重传。

    滑动窗口之选择重传-SR(Selective Repeat)

    GBN中接收方直接丢弃失序分组,简单但是资源浪费,SR协议就是为了解决浪费。

    解决浪费的核心就是不丢弃失序分组。但是作为接收方,传输层要保证按序把数据传输给上层的应用层,所以相比GBN,SR最大的改造是在接受方增加和缓存。作为发送方,SR在窗口内也有乱序的已经确认的数据分组。

    接收方窗口

    接收方缓存了正确接收但是乱序的数据。当ReceiveBase(期望的正确分组)到达时,数据会被交付给上层应用,同时接受窗口会移动。Receivebase=ReceiveBase+1

    发送方窗口

     示意图

    以上,滑动窗口的基本原理已经介绍完毕,通过对比发现,不管时GNB还是SR,为了保证数据不会乱序,都有一个共同特点:

    • 发送方,只有发送Base序号的数据确认后,窗口才会移动
    • 接收方,只有接收Base序号的数据收到后,才会把数据交给上层(GNB中,非Base序号的会丢弃。
  • 相关阅读:
    mod_rewrite
    敏捷开发
    转python和ruby的相同点
    ESB总线知识小结
    使用 squid 2.7 for windows 进行无缓存反向代理
    初探K2workflow
    没激情的工作
    多易拍 二次开发
    查看数二进制代码片段
    生成随机数
  • 原文地址:https://www.cnblogs.com/Brake/p/13855668.html
Copyright © 2011-2022 走看看