这次为分享一下有关于rdt的发展历程以及rdt协议演变,从rdt1.0-rdt2.0-rdt2.1-rdt2.2-rdt3.0的经历,使rdt一步步进行完善。
我们知道,TCP发送的报文段是交给IP层传送的。TCP下面的网络所提供的是不可靠的传输。因此,TCP要采用措施才能使得两个运输层之间的通信变可靠。
理想的传输条件有以下两个特点:
(1)传输信道不产生差错
(2)不管发送方以多块的速度发送数据,接收方总是来得及处理收到的数据
实际的网络不具备以上两个理想条件,但我们可以使用一些可靠传输协议,当出现差错时让发送方重传出现差错的数据,同时在接收方来不及处理收到的数据时,及时告诉方适当降低发送数据的速率。
rdt对应用层、传输层、链路层都重要
传输的不可靠特性决定了rdt的复杂性
只考虑单向数据传输,但控制信息双向流动
原理图如下:
利用状态机刻画传输协议(有线状态自动机)Rdt1.0
基于理想的可靠信道上可靠数据传输,底部信道可靠:1、不出端 2、不丢组
发送与接收 FSM独立
流程:发送方接收上层调用命令, 然后进行make_pkt然后发送给接收方,因为信道是完全理想的,所以接收方直接提取信息,然后传送给上层
Rdt2.0
基于产生错误的信道,其他因素不考虑,认为在理想的状态下。
底层可能翻转分组中的位
利用校验和检测位错误
从错误中恢复方法步骤
确定机制:接收方显式告知分组正确接收
NAK:接收方显式告知发送方有错
发送方收到NAK,重传
基于重传机制的rdt协议成为ARQ
相对于Rdt1.0来讲Rdt2.0引入新机制
差错检测
显示反馈信息 ACK/NAK
重传
Rdt2.0的FSM规约
在没有出错的情况下的操作
流程:发送方先等待上层应用调用,然后将数据封装成包,与rdt1.0不一样增加了checksun(校验和)然后发送给接收方,接收方在检验之后,接收、想上层发送、向发送方发送ACK。接收方接收到ACK不做重传,没有任何行动
在出错情况下的操作
流程:发送方进行发送,接收方接收后,出现校验和不正确,发送NAK,接收方接收到NAK,再次调用udt_send发送,进行重传,然后继续等待,这次没有出现错误,然后接收方检验无错,发送ACK,接收方接收到,不再重传
Rdt 2.1和Rdt 2.2
Rdt2.0的缺陷
如果NAK/ACK发生错误会怎么样?因为Rdt2.0只增加校验和和发送NAK/ACK,而再传送NAK/ACK的时候,可能发生错误,发生错误却检测不出来了。
方法:
为NAK/ACK增加校验和,检错并纠错;收到破坏ACK/NAK不知发送了什么,添加额外的控制信息;如果NAK/ACK坏掉,发送重传,不能简单的重传;不然会产生重复分组。
解决重复分组的问题?
序列号:发送方给每个分组增加序列号,接收方丢弃重复分组。
Rdt2.1
Rdt2.1:应对ACK/NAK的破坏
下图;发送方的流程图
接收方的流程图
流程:在rdt2.0的基础上,在打包数据包添加序列号同时也为NAK/ACK添加序列号 0/1,
假如现在接收方发送0号的数据包,如果接收方收到0号数据包,返回ACK,此时ACK发生翻转,接收方处于接收等待1号的状态,发送方继续发送0号数据,此时接收方会拒绝0号数据
如果当接收方收到0号数据包出错,返回NAK,NAK发送翻转,接收方处于接收0号数据状态,发送方发送1号数据,接收方不会接收
Rdt2.1与Rdt2.0对比
发送方: 接收方:
为每个分组加序列号 需要判断分组是否重复
需要校验ACK/NAK消息是否发送错误 当前所处状态提供了期望收到的分组序列号
四状态:必须“记住”“当前”的分组序列号
注意:接收方无法知道ACK/NAK是否被发送方正确收到
问题:我们真的需要两种确定信息吗?——不需要
Rdt2.2
Rdt 2.2:无NAK消息协议。只使用ACK
如何实现?
接收方通过ACK告知最后一个被正确接收的分组,在ACK消息中显式地加入被确认分组的序列号
发送方收到重复ACK之后,采取与收到NAK消息相同的动作,重传当前组
流程图,如下
Rdt 3.0
以上我们只是考虑到了位的翻转,如果信道发送错误、也可能丢失分组?那么“校验和+序列号+ACK+重传”够用吗?
Rdt 3.0 :增加时间序列
方法:发送方等待“合理”时间
如果没有收到ACK,重传
如果分组或ACK,只是延迟而不是丢失重传会产生重复
流程图:
下图中,左边是争取接收与发送,右边是发送方发送pkt时丢失,这连这种情况都能解决
下图左边是接收方在发送ACK的时候,丢失,发送方超过时间之后会 再次发送数据包,右图为接收方发送ACK还没有让接收方接收,接收方延迟时间设置较短。
Rdt 3.0 性能分析
rdt3.0能正确的发送,但是性能方面很差
发送方利用率:发送方时间占比
性能差的原因是由于停等操作引起