3.4可靠数据传输的原理
可靠传输的措施:
一步步的进行研究一系列的协议。
rdt 1.0认为信道完全可靠,协议最简单发送方只有发送动作,接收方只有接受动作。
rdt 2.0信道传输数据的时候可能出错,所以根据差错检验,接收方判断数据是否出错,没有错,返回一个ACK报文,出错了返回NAK报文,并且发送方重传。
rdt 2.1 不管是数据报可能出错,ACK确认报文也可能出错,所以rdt 2.1又加上了序号(0,1)进行判断。
rdt 2.2 是无NAK的,通过判断ACK是否冗余,判断是否出错。
rdt 3.0 如果确认报丢包了,那么发送方处于等待接受确认报文状态,不会接受上层的数据进行发送,接收方处于等待接收数据的状态,没有下层的数据。这样就会造成死锁。
怎么样判断是否丢包了,加上一个倒计数定时器。
流水线:
rdt 3.0已经很可靠了,但是还有一个问题,就是浪费问题,发送端发送完数据到接收到确认报文这段时间是完全浪费的。流水线解决了这个问题。
流水线允许发送方发送多个(有最多限制)分组无需等待确认。措施:
- 必须增加序号范围,每个运输的分组必须有一个唯一的序号。
- 协议的发送方和接收方两端必须能缓存多个分组
- 有差错恢复的方法:回退N步,选择重传
3.4.3 回退N步(GBN)
流水线允许一个发送多个分组而不需要确认。如下图:
黑色:已被确认的分组
灰色:发送并且未被确认的分组
浅灰色:可用发送分组
白色:不可用(也就是在滑动窗口外部的分组)
定义:基序号(base)为最早未被确认的分组(图中灰色第一个)
下一个序号(nextseqnum)最小未使用的分组(图中浅灰色第一个)
窗口大小为N
流程:
发送方:
- 发送端收到上层需要传输的数据请求,检查nextseqnum是否小于base + N – 1(即是否在窗口内),已确定是否窗口内是否还有可用空间。
- 如果还有可用空间就发送。
- 没有可用空间,要么缓存,要么返回给上层,以便以后发送。
- 发送方采取累计确认,窗口内的所有分组都确认,那么窗口移动到窗口末尾的下一个位置。
接收方:
- 接收方会返回一个确认好ACK(N)表示N之前的分组已经全部收到。
- 如果n分组丢失,收到n + 1分组,那么会返回ACK(n)表示n分组 之前的分组都收到,并且丢弃n + 1分组(这样做很浪费,在SR中会得到解决)。
3.4.4 选择重传(SR)
GBN用互动窗口来解决流水线的问题,但是有一个缺点就是,当中间分组发生丢失的时候,会选择丢弃丢失分组之后接收到的分组,实际传输中很浪费时间。
而SR顾名思义选择重传,会缓存下来丢失分组之后丢失的分组,并且重传丢失的分组。
如下图:
黑色:已确认分组
灰色:已发送并且未确认分组
浅灰色:可用分组
白色:为被确认分组
定义:基序号(base)为最早未被确认的分组(图中灰色第一个)
下一个序号(nextseqnum)最小未使用的分组(图中浅灰色第一个)
窗口大小为N
流程:
发送方:
- 发送方从上层接收到数据,SR检查nextsqrnum是否小于base + N – 1
- 如果是,发送数据
- 否则,要么缓存,要么返回给上层,以便以后发送。
- 接收方收到发送方的确认报文ACK(N),判断是否是base(也就是滑动窗口的第一个)
- 如果是,那么将窗口移动到最小序号未被确认的分组处
- 如果窗口移动了,如果还有分组落在窗口内并且未被发送,那么发送未被发送分组。
接收方:
- 判断分组是否处于base 到 base + N + 1。
- 如果是,那么返回发送方一个确认报文ACK(N)(冗余的也没事,发送方会根据三次ACK进行丢包判断),如果以前没收到这个报文就进行缓存,如果这个报文序号时base,将base到第一个没确认的报文前 的报文上交。
- 收到滑动窗口内的报文必须返回一个ACK(N)报文表示N之前的分组已经全部收到
- 其他情况忽略分组。