主机内部的传输数据被封装为“报文段”,而在主机之间,报文段加上了ip地址头部,我们称为“分组”,为了简便,我们简称为“包”

总览

什么叫不可靠传输?简单来说,这种传输中,在接收方可能出现以下问题,可靠传输就是通过各种手段解决
可靠数据传输简称Rdt
书中Rdt1.0表示再可靠信道上传输,当然就是可靠传输
而实际上,信道不可靠,因为他会出现以下问题

问题 方案
差错(包内部字节乱序,丢失等) ACK与NAK反馈
冗余(重复传了同一个包) 分组序号
乱序(包之间排序出现混乱) ACK与NAK序号
丢包 倒计数定时器

可能现在还看不太懂方案是啥意思,没关系,本片博客就是为解释上面这个表而生成的
解决了以上问题,就成为可靠传输了

差错

关键词:校验和,ACK与NAK重传,停等协议

设计思路

如果传输过程出差错(指包内部位丢失,错位等),我们要做什么?
我们只能做,并且必须做两点:

  1. 接收方检测出差错,并告诉发送方
  2. 错了已经不能回头,只能重新传一次

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

SR