加油!偷博仔
今天遇见两首顾城的诗
黑夜给了我黑色眼睛
我却用它寻找光明
————《一代人》 1979年4月
在你的门前
我堆起一个雪人
代表笨拙的我
把你久等
你拿出一颗棒糖
一颗甜甜的心
埋进雪里
说这样就会高兴
雪人没有笑
一直没作声
直到春天的骄阳
把它融化干净
人在哪呢
心在哪呢
小小的泪潭边
只有蜜蜂
————《雪人》1980年2月
好,沉静了心情,正片开始。
可靠数据传输原理。
一、可靠数据传输(rdt)的原理
rdt(reliable data transfer))在应用层、传输层和数据链路层都很很重要
是网络Top 10问题之一重要
什么才叫可靠呢,传输的数据,原原本本交付,不出错不重复不失序不丢失
Reliable&& unreliable channel
1.1可靠数据传输:问题描述
中间两个大方框 就是rdt实体。
这四个函数,分别是接收方和发送方rdt与上层、下层的接口
1.2可靠数据传输:问题描述(续)
我们将:
渐增式地开发可靠数据传输协议( rdt )的发送方和接收方
只考虑单向数据传输
但控制信息是双向流动的!
双向的数据传输问题实际上是2个单向数据传输问题的综合
使用有限状态机 (FSM) 来描述发送方和接收方
所谓渐增式:
就是先假定可靠传输的条件一一具备,然后逐个假定条件不可靠,rdt逐个针对该不可靠条件,实现哪些机制。
然后采用有限状态机来描述状态的改变。
下面一步一步升级rdt
2.1Rdt1.0: 在可靠信道上的可靠数据传输
Rdt1.0描述:
- 下层的信道是完全可靠的
没有比特出错
没有分组丢失- 发送方和接收方的FSM
发送方将数据发送到下层信道
接收方从下层信道接收数据
发送方:上层来了data,封装成packet、下发packet;
接收方:下层来了packet,解封装,上交data
这就相当于,rdt啥也不干。啥事下属都干好了,rdt只管抽烟喝酒烫头 (只管来什么发什么,送什么收什么)
2.2Rdt2.0:具有比特差错的信道
Rdt2.0描述:
下层信道可能会出错:将分组中的比特翻转
用校验和来检测比特差错 问题:怎样从差错中恢复:
确认(ACK, acknowledgment):接收方显式地告诉发送方分组已被正确接收
否定确认( NAK,negative acknowledgment): 接收方显式地告诉发送方分组发生了差错
- 发送方收到NAK后,发送方重传分组
rdt2.0中的新机制:采用差错控制编码进行差错检测
发送方差错控制编码、缓存
接收方使用编码检错
接收方的反馈:控制报文(ACK,NAK):接收方→发送方
发送方收到反馈相应的动作
rdt2.0:FSM描述
发送方,有两个状态,等待上层调用和等待ACK或NAK
- 发送方有一个副本,以便检错重传
- 发送方在第一个状态,等待上层调用,来了一个data,计算checksum, 封装成packet,下发。
- 于是转换成第二个状态,等待ack或nak 。
接收方,只有一个状态。
- 如果收到的packet(rcvpkt),是corrupt(腐败的,这里就是有误的)的,那么feedback NAK(udt_send(NAK)).
- 如果notcorrupt,就解封装(extract()),上交data(deliver_data(data)),并且feedback ACK(udt_send(ACK))
所以现在,聪明的,你看懂了这个有限状态机的描述形式吧。
那,就自己观摩下面2个FSM的描述吧
rdt2.0:没有差错时的操作
rdt2.0:有差错时
2.3rdt2.0的致命缺陷!-> rdt2.1
- 如果ACK/NAK出错?
发送方不知道接收方发生了什么事情!
发送方如何做? 重传?可能重复 不重传?可能死锁(或出错)
需要引入新的机制: 序号(Sequence Number) - 处理重复:
发送方在每个分组中加入序号
如果ACK/NAK出错,发送方重传当前分组
接收方丢弃(不发给上层)重复分组
rdt2.1:发送方处理出错的ACK/NAK
从虚线的位置开始看。
此时,上层来的data除了data,checksum封装到packet中,还有序号。
rdt2.1:接收方处理出错的ACK/NAK
rdt2.1:讨论
- 发送方:
在分组中加入序列号
两个序列号(0,1)就足够了: 一次只发送一个未经确认的分组
必须检测ACK/NAK是否出错(需要EDC )
状态数变成了两倍: 必须记住当前分组的序列号为0还是1- 接收方:
必须检测接收到的分组是否是重复的
状态会指示希望接收到的分组的序号为0还是1
注意:接收方并不知道发送方是否正确收到了其ACK/NAK
没有安排确认的确认 也没有确认的确认的确认。
具体解释见下页
rdt2.1的运行
一张图,明了啦!
2.3rdt2.2:无NAK的协议
rdt2.2 description:
- 功能同rdt2.1,但只使用ACK(ack 要编号)
接收方对最后正确接收的分组发ACK,以替代NAK 接收方必须显式地包含被正确接收分组的序号
当收到重复的ACK(如:再次收到ack0)时,发送方与收到NAK采取相同的动作:
重传当前分组
为后面的一次发送多个数据单位做一个准备
- 一次能够发送多个
每一个的应答都有:ACK,NACK;麻烦
用前一个数据单位的ACK,代替本数据单位的NAK
确认信息减少一半,协议处理简单
用前一个序号ack代替当前nak
rdt2.2的运行
rdt2.2:发送方和接收方片断
2.4rdt3.0:具有比特差错和分组丢失的信道
新的假设:
下层信道可能会丢失分组(数据或ACK)(好比之前说的路由器队列排满了,新来的就被drop掉)
- 会死锁
- 机制还不够处理这种状况:
• 检验和
• 序列号
• ACK
• 重传
方法:(超时重传)
-
发送方等待ACK一段合理的时间
(链路层的timeout时间确定的传输层timeout时间是适应式的;所谓适应式的,现在我还不懂…郑老师又说会在TCP的timeout设置那里去讲) -
发送端超时重传:如果到时没有收到ACK->重传
-
问题:如果分组(或ACK )只是被延迟了:
重传将会导致数据重复,但利用序列号已经可以处理这个问题
接收方必须指明被正确接收的序列号 -
需要一个倒计数定时器
rdt3.0 发送方
注意注意,rdt3.0加入了start_timer动作和timeout事件。
rdt3.0的运行
rdt3.0的性能:
rdt3.0可以工作,但链路容量比较大的情况下,性能很差
链路容量比较大,一次发一个PDU 的不能够充分利用链路的传输能力就好像交通规则(协议)规定,宽敞的(信道容量大)高速公路上(链路),每次只允许跑一台车(1bit),或者一个车队(1packet),正常情况下跑完全程高速, ack确认。然后再让下台车或下个车队上高速跑。就产生高速公路(链路)利用率极低的情况。
信道容纳bit的个数: 信道延时/一个bit的传输时间
往返传播延时30ms,分组传输延时0.008ms
当物理资源的利用率将近100%,那么瓶颈就在于物理链路的带宽了
rdt3.0:停——等操作(rdt3.0也是一种 “停止等待协议”)
那为了提高利用率,让宽敞的信道忙起来,就… (当然如果信道不宽,一次发一个也许才是)
2.4.1流水线(pipeline)(提高链路利用率)
流水线: 允许发送方在未得到对方确认的情况下一次发送多个分组
- 必须增加序号的范围:用多个bit表示分组的序号
- 在发送方/接收方要有缓冲区 (缓冲技术,对抗发送/接收速度不匹配的情况)
- 发送方缓冲:未得到确认,可能需要重传;
- 接收方缓存:上层用户取用数据的速率≠接收到的数据速率;接收到的数据可能乱序,排序交付(可靠)
两种通用的流水线协议:回退N步(GBN)和选择重传(SR)
2.4.2通用(为后文协议铺垫):滑动窗口(slide window)协议
-
发送缓冲区
形式:内存中的一个区域,落入缓冲区的分组可以发送
功能:用于存放已发送,但是没有未经确认的分组
必要性:需要重发时可用 -
发送缓冲区的大小:
一次最多可以发送多少个未经确认的分组
停止等待协议=1 流水线协议>1,合理的值,不能很大,链路利用率不能>100% -
发送缓冲区中的分组
未发送的:落入发送缓冲区的分组,可以连续发送出去;
已发送、等待确认的:发送缓冲区的分组只有得到确认才能删除
2.4.3 发送窗口滑动过程-相对表示方法
采用相对移动方式表示,分组不动
可缓冲范围移动,代表一段可以发送的权力
let me explain:
浅蓝色:分组已发送且已确认。
粉红色:分组已发送且未确认。
白色:分组未发送。
·
图中“真正滑动过程”, 绿色线条(发送缓冲区)不动,数字队列(分组)移动
相对滑动表示,真正滑动的相对滑动。
- 发送窗口:发送缓冲区内容的一个范围 。是发送缓冲区的一个子集
那些已发送但是未经确认分组的序号构成的空间 - 发送窗口的最大值<=发送缓冲区的值
- 一开始:没有发送任何一个分组
后沿=前沿
之间为发送窗口的尺寸=0 - 每发送一个分组,前沿前移一个单位
- 发送窗口的移动->前沿移动
图中前沿左边的箭头,应该随着深蓝色向右同步移动
前沿左边的箭头最后移动到位置4。所以此时发送窗口尺寸=5
- 发送窗口的移动->后沿移动
再看一个生动的发送窗口图
2.4.4 滑动窗口(slide window)协议——接收窗口
接收窗口 (receiving window)=接收缓冲区
- 只有收到的分组序号落入接收窗口内才允许接收
若序号在接收窗口之外,则丢弃; - 接收窗口尺寸Wr=1,则只能顺序接收;
- 接收窗口尺寸Wr>1 ,则可以乱序接收
(但提交给上层的分组,要按序)
除了丢弃2号分组,还要回馈一个按顺序接收的最高序号的ack,比方说此时ack = 1。
看下图:
滑动,不能失序
正常情况下的2个窗口互动
滑动窗口看到这里,有一种浑然一体的感觉。
到这里,铺垫完了,好像也说的差不多了。
铺垫的就是GBN(回退n步协议(GO-BACK-N))协议
和SR(选择重传协议(selective repeat)协议
- 当发送窗口Ws > 1, 接收窗口Wr = 1时,叫做GBN协议
- 当发送窗口Ws > 1, 接收窗口Wr > 1时,叫做SR协议
其实还有一种协议:停止等待协议(stop-and-wait)
- 当发送窗口Ws = 1, 接收窗口Wr = 1时,叫停止等待协议
回顾一下异常情况的窗口互动:
超时,Ws全部重传
超时Ws选择重传
2.4.5 GBN协议和SR协议的异同
2.4.6流水线协议:总结
维护的定时器个数不同:GBN 1个;SR 多个。
2.4.7 GBN:发送方与接收方,扩展的FSM,运行的GBN图
用有限状态机来文字转图片:发送方扩展FSM
Explanation:
N,发送缓冲区大小
base ,发送窗口后沿。
nextseqnum,发送窗口前沿。
用有限状态机来文字转图片:接收方扩展FSM
此时接收窗口在5的位置,红色6,代表乱序收到6号分组,丢弃。
此时udt_send(sndpkt)中,就包含了ack4.
最后由于pkt2timeout,就重传了一遍未确认的所有分组
又是浑然天成的感觉。
最后再来感受一下SR协议
2.4.8 选择重传SR
由于pkt2 timeout,于是单独,pkt2 resent,
2.4.9对比GBN和SR与窗口的最大尺寸
本篇结束。
转载:https://blog.csdn.net/m0_46156900/article/details/113817906