rdt1.0
将数据的传输信道理想化,视为完全可靠,不丢包,不损失bit ,在这样的情况下,发送端发送数据,接收端直接接收,并不考虑**丢包,超时****这些问题。
该协议中,都是直接发送,直接接收。
rdt2.0
" 在 rdt2.0 中,我们将传输通道视为有可能发生比特错误 "
引进使用差错检测:检验发过来的包有没有错误 (校验和)——判断决定是否重传
接收方的反馈:接收方返回 NAK 或者 ACK ,分别对应数据错误和数据正确,这个也可以理解,总要告诉发送端,你发过来的是对还是错。
(假设:接收方收到数据A无误,向发送方传递ACK,返回值中途原值ACK →NAK。发送方认为数据A无误,立即进入下一个状态。但是接收方一直等待发送方重传数据A.)
rdt2.1
"发现了 rdt2.0 的致命缺陷,原来接收端返回的值也可能会出错啊,万一NAK出错变成ACK(比特翻转)了呢?"
该协议在 2.0 基础上增加了一个序号值(在这里,**该序号在当前协议中只使用 0 和1 ,交替排列****),这样一来,发送端和接收端都有了两种序号状态, 0 和 1 。
发送端在 0 序号时发送数据包,接收端此时期待 0 序号的数据包。如果数据发送时发生 bit (比特)受损,此时接收端直接通过检验和发现错误,并返回 NAK ,发送端接到 NAK 的返回值,然后重新发送 0 序号数据包。(但是注意,这完全和 rdt2.0 没有任何分别,这是一种理想的状态!!!)
接收端成功接收,但是返回 ACK的时候发生了bit(比特)翻转,变成了 NCK ,这才是我们讨论的重点!!接下来,我需要画一张图,来理清楚当返回错误的时候,怎么通过序号来判断并重传数据。 )
rdt2.2
需要返回 NAK , ACK 两种状态可能太麻烦了,就将其全部改为ACK 只是返回的时候顺便返回序号。
接收端收到包,不管正确与否,都返回 ACK ,同时附上序号,这个序号嘞,就是数据包发送过来时的序号。另外的参照上图,相信同学们都能有所收获。
rdt3.0
上图是 rdt3.0 发送方的 FSM 图,就拿右上角的状态举例,此时发送端等待接收方返回的带有“0”序号的 ACK ,它有三种行为:
倒计时定时器:规定时间内,若无反馈,则重传
第一种:过程中未丢包,但是数据比特出错或者*不符合序号*,和我们讨论过的 rdt2.2 差不多,那么此时就没有任何动作,毫无作为就好了,等到时间间隔一到,当做超时处理,重发数据。
第二种:是真正的丢包了,所以时间一到,重新发送。
第三种最理想:啥事没有,一切正常,跳到下一个状态,等待发送下一个包
上面我加粗了一个**不符合序号。****
这里的**不符合序号****,与期待的序号不符,有两种情况:
1. 接收端反馈过程中,代表序号的那个 bit 错误,进行了翻转——这就和 rdt2.2 中一样
2. 我们上面引入了超时机制,但是有一种情形,万一我发出去的数据包并没有丢失,只是它跑的太慢而已呢??那么时间一到,发送端误以为丢包,重新发了一遍咋办??这就造成,接收端才收到你晚来的数据 0 号,还给你个 0 ,这时候你重传的 0 号包接着又到了,接收端又给你一个0 ,作为发送端,我会先后收到两个 0 ,就注定后面一个 0 会被期待 1 号的状态捕捉,这时发送端启动第一种处理方式——不作为,啥都不做。
rdt3.0不足,比如:
- 效率太慢,由于停等方式的存在,一个包没处理好,发送端会一直等着。
- 超时机制的时间间隔怎么确定?长了不行,太慢,短了么,又会经常有重复发包的情况。