1 什么叫可靠
数据在传输过程中,不错,不丢,不乱。
2 信道是不可靠的
可靠数据传输对应用层、传输层、链路层都很重要。
如下图,数据在信道中传输是不可靠的。
信道的不可靠特性决定了可靠数据传输协议(rdt)的复杂性
3 可靠传输协议的基本架构
4 可靠传输协议设计
渐进地设计可靠数据传输协议的发送方和接收方,一步一步的完善可靠传输协议的设计。只考虑单向数据传输,控制信息可以双向流动。
利用状态机(Finite State Machine, FSM)刻画传输协议
4.1 简单版本1.0
假设底层信道完全可靠,不会发生错误,不会丢弃分组
在这种前提下,设计就非常简单了
发送方:
状态wait for call from above:等待上层应用发送数据过来,此时可接收上层数据
当上层应用发送数据过来,通过信道将数据分组发送到接收方(此时不接收上层应用数据),发送完成,回到wait for call from above状态
接收方:
状态wait for call from above:等待发送方发送数据分组过来
当发送方发送数据分组过来,接收数据分组,接收完成,回到wait for call from above状态
4.2 进一步版本2.0
假设底层信道不可靠,但是只会翻转分组中的位,也就是0变1,1变0
要保证可靠,就需要增加一些东西:
校验和(用来检测位错误)
确认机制:接收方校验无误,给发送方返回ACK,有误,给接收方返回NAK
重发机制:发送方收到NAK,重新发送
停等协议:发送方发送数据分组,要等待接收方的应答,根据应答再进行下一个行动。保证数据分组一个一个有序的发送。
发送方:
状态wait for call from above:等待上层应用发送数据过来,此时可接收上层数据
当上层应用发送数据过来,通过信道将数据分组发送到接收方(此时不接收上层应用数据),此时状态变为 wait for ack or nak(等待接收方的应答)
接收方:
状态-wait for call from above:等待发送方发送数据分组过来
当发送方发送数据分组过来,接收数据分组,接收完成,检查数据分组
无误:接收方返回ACK,变为wait for call from above状态,发送方收到ACK,此次数据分组传输成功,变为wait for call from above状态
有误:接收方返回NAK,变为wait for call from above状态,发送方收到NAK,此次数据分组传输失败,重新传输数据分组
4.3 再进一步3.0
在2.0版本,还存在问题,如果ACK/NAK这个应答发生错误或者被破坏了,发送方就不知道数据到底发送成功还是失败了。
方案:如果ACK/NAK坏掉,发送方重传。
这样又会存在数据分组重复问题,接收方正确收到数据分组,返回ACK,ACK被破坏了,发送方重发,接收方接收,这样一份数据分组收了两份,重复了。
方案:发送方给每个数据分组增加一个序列号,接收方丢弃重复的数据分组。由于采用的停等模式,所以只需要0和1两个数字作为序列号就足够了。
发送方应对ACK/NAK破坏
接收方应对ACK/NAK破坏
4.4 进一步优化4.0
3.0应答采用的ACK和NAK,可以去掉NAK,使用ACK配合序号来应答。
发送方发送序号为0的数据分组,接收方应答ACK+0表示成功,应答ACK+1表示失败
同理,发送方发送序号为1的数据分组,接收方应答ACK+1表示成功,应答ACK+0表示失败
4.5 继续完善5.0
在4.0,只是信道只会发生位变错误,实际上信道既可能发生错误,也可能丢失数据。
那么校验和 + 序列号 + ACK + 重传就不够用了
方案:发送方加一个等待超时机制,加一个定时器。发送方等待“合理”时间,超过这个时间,如果没收到ACK,重传。如果分组或ACK只是延迟而不是丢了,重传会产生重复,序列号机制能够处理重复的问题
4.6 性能提升6.0
4.6.1 缺点
5.0能够正确工作,但性能很差。
4.6.2 流水线机制
不采用停等机制,而是流水线机制。也就是发送方发送一个数据分组,不需要等待接收方的应答,就发送下一个数据分组。这样,效率就会高很多,提高资源利用率。
4.6.3 滑动窗口协议介绍
分组头部包含k-bit序列号,所以共有2^k个序列号。
窗口尺寸为N,所以最多能有N个数据分组处于发送未响应的状态
超时事件:若序号为n的数据分组超时了,重传序号列大于等于n的所有分组
4.6.5 接收方(GBN协议)
按序接收,不是按序到达的直接舍弃。
累计应答机制:发送拥有最高序列号的、已被正确接收的分组的ACK
4.6.6 示例
发送方窗口大小为4
1)发送方发送序号为0/1/2/3的数据分组,由于窗口大小是4,不能继续发送,等待应答
2)接收方收到0,数据分组没有问题,应答ACK0,窗口右移一格
3)接收方收到1,数据分组没有问题,应答ACK1,窗口右移一格
4)2丢失了
5)接收方收到3,数据分组没有问题,不是按序到达,直接舍弃,返回ACK1(累计应答机制:发送拥有最高序列号的、已被正确接收的分组的ACK)
6)发送方收到ACK0,窗口右移一格,发送数据分组4
7)发送方收到ACK1,窗口右移一格,发送数据分组5
8)接收方收到4,数据分组没有问题,不是按序到达,直接舍弃,返回ACK1
9)接收方收到5,数据分组没有问题,不是按序到达,直接舍弃,返回ACK1
10)发送方一直没收到ACK2,超时了,重发2/3/4/5(超时事件:若序号为n的数据分组超时了,重传序号列大于等于n,且还未收到ACK的所有分组)
11)接收方收到2,数据分组没有问题,应答ACK2,窗口右移一格
12)接收方收到3,应答ACK3,窗口右移一格
13)接收方收到4,应答ACK4,窗口右移一格
14)接收方收到5,应答ACK5,窗口右移一格
......
4.7 性能提升7.0
4.7.1 缺点
6.0能够采用GEB协议能正确工作,相较于5.0效率有所提升。
但是,为了保证正确有序,接收方会舍弃不是按序到达的数据分组。而发送方一旦某个序号没有正确发送,序号大于等于它的全部需要重发。
这样效率也损耗了很多。
为了增加效率,采用SR协议。相较于GBN,它增加了缓存机制,它在接收方也设置了窗口,还设置了缓存。
4.7.2 发送方(SR协议)
分组头部包含k-bit序列号,所以共有2^k个序列号。(序号个数需要大于等于发送方窗口大小加上接收方窗口大小以避免接收方在一个窗口收到同样序号的数据分组)。
窗口尺寸为N,所以最多能有N个数据分组处于发送未响应的状态
超时事件:若序号为n的数据分组超时了,重传序号列大于等于n,且还未收到ACK的所有分组

4.7.3 接收方(SR协议)
ACK单一应答机制: 针对接收到的数据对应返回
乱序到达的,若有空闲的窗口,缓存起来。无空闲窗口,直接舍弃。

4.7.4 示例
发送方窗口大小为4,接收方窗口大小也为4,共有序号为0-5的6个数据分组要发送
1)发送方发送序号为0/1/2/3的数据分组,由于窗口大小是4,不能继续发送,等待应答
2)接收方收到0,数据分组没有问题,应答ACK0,窗口右移一格
3)接收方收到1,数据分组没有问题,应答ACK1,窗口右移一格
4)2丢失了
5)接收方收到3,数据分组没有问题,不是按序到达,接收窗口有空闲,缓存起来,应答ACK3(ACK单一应答机制: 针对接收到的数据对应返回)
6)发送方收到ACK0,窗口右移一格,发送数据分组4
7)发送方收到ACK1,窗口右移一格,发送数据分组5
8)接收方收到4,数据分组没有问题,不是按序到达,接收窗口有空闲,缓存起来,应答ACK4
9)接收方收到5,数据分组没有问题,不是按序到达,接收窗口有空闲,缓存起来,应答ACK5
10)发送方一致没收到ACK2,超时了,重发2(超时事件:若序号为n的数据分组超时了,重传序号列大于等于n,且还未收到ACK的所有分组)
11)接收方收到2,数据分组没有问题,应答ACK2,窗口右移一格
12)缓存中已有3,取出交给上层应用,窗口右移一格
13)缓存中已有4,取出交给上层应用,窗口右移一格
14)缓存中已有5,取出交给上层应用,窗口右移一格
......
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?