主机内部的传输数据被封装为“报文段”,而在主机之间,报文段加上了ip地址头部,我们称为“分组”,为了简便,我们简称为“包”
总览
什么叫不可靠传输?简单来说,这种传输中,在接收方可能出现以下问题,可靠传输就是通过各种手段解决
可靠数据传输简称Rdt
书中Rdt1.0表示再可靠信道上传输,当然就是可靠传输
而实际上,信道不可靠,因为他会出现以下问题
问题 | 方案 |
---|---|
差错(包内部字节乱序,丢失等) | ACK与NAK反馈 |
冗余(重复传了同一个包) | 分组序号 |
乱序(包之间排序出现混乱) | ACK与NAK序号 |
丢包 | 倒计数定时器 |
可能现在还看不太懂方案是啥意思,没关系,本片博客就是为解释上面这个表而生成的
解决了以上问题,就成为可靠传输了
差错
关键词:校验和,ACK与NAK重传,停等协议
设计思路
如果传输过程出差错(指包内部位丢失,错位等),我们要做什么?
我们只能做,并且必须做两点:
- 接收方检测出差错,并告诉发送方
- 错了已经不能回头,只能重新传一次
ACK确认与ARQ协议
如果接收方成功收到分组,并且通过校验和判定这个包没出差错,就会回发一个“ACK”(positive acknowledgment)确认.
如果检测出差错,就发送"NAK"(negative acknowledgment)
接收方通过发送方的回复判断发送是否出现了差错(所以收到回复之前他不会继续发),当收到ACK,就继续发下一个包,如果是NAK,就重发这个包
这种具有自动重传机制的可靠数据传输协议称为ARQ(auto repeat reQuest)协议
下图是发送端的状态,有两种,一种是发送状态,在这个状态中,上层可以调用rdt_send(data)方法指示其发送数据,并进入等待状态,另一种是等待状态,两个状态可以互转,等待状态接受到
横线上面为调用该状态的方法,下面为该状态自己进行的方法
接收端状态(注意此时是下层调用这个状态,因为接收端的数据是从下层往上层传的)
现在我们来演示,假设没有错误
如图所示
红圈表示初始状态
data会加上checksum打包后发到接收端,发送端停等,然后接收端发回ACK确认,发送方状态变化,一次发送执行完毕
出错的时候同理
解决了差错问题
Rdt2.0缺陷:没有考虑ACK与NAK的错误情况
冗余与乱序
关键词:序列号与升级版ACK
Rdt2.1
如果ACK与NAK出错,那么发送方将会收到一个不可识别的确认消息
解决方法:重传
问题:导致发送的分组重复,产生冗余问题
思路
给分组加序号(0,1),接收方收到两个相同序号的分组时,抛弃后来的,同时要发ACK,让发送方知道,避免他重传
设计方案
加上校验和,状态翻倍,再加上序列号,状态再翻倍
接收方也是,分为希望收到0的状态和希望收到1的状态
Rdt2.2
原来的NAK作用在于告诉发送方我没收到某个分组
现在用升级版ACK,也就是在ACK中加上确认的序列号,告诉发送方:“我已经收到了这个序列号的分组”
发送方识别下一次要发哪一个分组
总状态,上面是发送方,下面是接收方
丢包
关键词:定时器
如果发送方发的包半路丢失,接收方不知道情况,导致发送方永远等下去
思路
很简单,设计发送方合理的等待时间,超过就……
哈哈,当然还是伟大的重传啦!!!
问题:包没有丢失,ACK延迟到重传之后来了,导致冗余(不过我们Rdt2.2已经解决了问题)
设计方案
a为正常发送,b为发送方丢包,黑线为定时器时间,超过即重发
c为接收方丢包(ACK丢失),d为ACK延迟,导致重发冗余
d的最后收到了姗姗来迟的ACK1,但是他要的是ACK0,此时该怎么办?(以后再解释)
性能
从以上可以看到,停等协议,发送方很多时间往往在等待,所以导致他的性能很差
举例说明
直观感受,两个竖线之间的面积为可用网络资源,青色部分为用到的,所以性能很差,利用率仅为0.00027
方案:流水线协议
如图,同时发3个就可以将性能提高3倍
新问题:分组序号
每多发一个分组,就必须多分配一个序列号,原来仅有0和1,现在需要更多的序号
新方案:滑动串口协议
有两种滑动窗口协议
GBN
Go-Back-n