一、首先,什么是可靠的数据传输?
不错(没有比特差错),不丢(丢包),不乱(按序到达)
二、然后一步步从0来构建这个可靠数据传输协议,看看他是怎么形成的。
三、构建前的约定:
1.用rdt表示可靠数据传输协议。
2.因为这里讨论的理论适用于一般的计算机网络,而不只是传输层,所以采用名词“分组”而不是传输层的“报文段”。
3.用“有限状态机”(FSM)来描述接受方和发送方的图。(有限状态机:即表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型,简单理解为一种画图方法)
四、开始构建
1.rdt1.0版本(假设底层信道是完全可靠的,底层是不丢不错不乱的)
这种情况最简单,也是最理想的。那么直接拿着数据往下传或者往上传就好啦。有限状态机描述如下:
原英文版:
中文版:
2.rdt2.0版本(底层信道不再完全可靠,出现比特差错/受损)
*那么对于受损的分组,将要进行重传。基于这样重传机制的可靠数据传输协议称为自动重传请求(ARQ)协 议。
*ARQ协议中还需要另外三种协议功能来处理比特差错的情况:
1.差错检测。简单来说,就是需要一种机制使接收方能检测到出现了差错。类似UDP校验和,这种机制 需要额外的比特,这些额外的比特放在rdt2.0数据分组的分组校验和字段中。
2.接收方反馈。接收方得告诉发送方,他是否接受到了正确分组。rdt2.0中接受到正确的就发ACK分组, 错误的就发NAK分组,理论上只需要一个比特1表示ACK,0表示NAK.
3.重传。接到NAK重传该分组。
*有限状态机(FSM)如下(英文不明白可以对比rdt1.0中英文):
*像这种接收到ACK才能发生事件。rdt.0这样的协议也称为停等协议。
3.rdt2.1(rdt2.0中存在问题,如果ACK/NAK分组损坏了怎么办?)
*解决方法是收到损坏的ACK/NAK分组那么进行重传。
*但是!不能简单重传,那会造成冗余分组,接受方将不知道这到底是新发的还是上一个的重传!
*那么怎么解决这个问题?
一个简单方法(几乎所有现有的数据传输协议中,包括TCP都采用的这个)是在分组中添加一新字段, 让发送对分组编号。接受方根据编号就知道这是新分组还是重传了。
rdt2.1这种停等协议,加入0,1即可。一次发带0的一次发带1,以此往复,以此区分上一次和这一次。
*有限状态机(FSM)如下:
4.rdt2.2(无NAK消息协议)
*我们真的需要ACK和NAK两种消息吗?
不需要。ACK一种就够了。
*如何做到?
在ACK消息中加入最后一次正确接收的序列号。
*原理
因为正常情况这次的发送分组序号和上次相反,上次是0这次则会是1.
如果接受成功,那么发送方接收到的ACK将与上一次序号不同。
如果接收失败,那么发送方接收到的ACK将会和上次序号一样。这样就触发重传。
*FSM(有限状态机)如下
5.rdt3.0(底层是 有比特差错 并且 会丢包 的信道)
rdt2.2基础上已经解决比特差错,实际也可以解决发生丢包后如何处理。那么问题的关键就是如何检查丢包。
方法: 发送方等待”合理”的时间内,用倒计时定时器,
如果没收到ACK,重传
如果分组或ACK只是延迟而不是丢了那么 重传会产生重复,序号机制能处理(rdt2.2已解决)
FSM(有限状态机):
*因为分组序号在0 1 之间交替,因此rdt3.0有时也被称为比特交替协议。
*至此,我们得到了一个可靠数据传输协议!
五、后续
1.rdt3.0是一个功能正确的协议,但是因为它是一个停等协议,性能非常糟糕。
2.解决办法是打破停等协议。不使用停等方式运行,运行发送方发送多个分组而无需等待确认
许多发送的分组可以被看成填充到一条流水线中,故这种技术被称为流水线机制。
3.流水线技术对可靠数据传输协议可带来如下影响:
--更大的序列号范围
--发送方和接收方需要更大空间缓存分组
--解决流水线的差错恢复有两种基本方法:回退N步(GBN,滑动窗口协议的一种实现)和选择重传(SR)
4.滑动窗口协议
窗口:
窗口尺寸为N:最多有N个等待确认的消息
滑动窗口
随着协议的运行,窗口在序列号空间内向前滑动
滑动窗口协议有GBN和SR
4.GBN(回退N步协议),发送方看到的序号(注意!这是一次性发送的窗口情况,全结束后,下一波继续会有一张重新的窗口情况,比如下面这个表明一次性最多发56个):
*采用的累积确认的机制,如果收到的是ACK(N),表示确认到N的序列号分组均已被正确接收
*为空中的分组设置计时器(丢包问题)
*超时Timeout(N)事件:重传序列号大于等于N,还未收到ACK的所有分组。(这里潜在有资源浪费问 题)