(给爷整吐了 还有状态机要背)
可靠数据传输原理
可靠数据传输的问题在运输层、链路层及应用层都会出现。
- 数据通过一条可靠的信道传输
- 即传输的数据不出错,丢失,并按照发送的顺序传送
可靠传输实现
设计可靠数据传输协议
低层信道不太可靠,通过使用可靠数据传输协议来保证可靠的数据传输。
分别设计可靠数据传输协议的发送方和接收方。
基本实现
发送方 | 接收方 |
---|---|
通过*rdt_send()*函数调用可靠数据传输协议的发送方(rdt表示“可靠数据传输”协议)。 | 当一个分组从信道抵达时,调用*rdt_rcv()*接收; |
*udt_send()*用来发送分组给对方(udt表示“不可靠数据传输”) | 调用*deliver_data()*将数据交付给上层。 |
- 只考虑单向数据传输,数据传输从发送方到接收方
- 发送方和接收方可以来回交换控制分组(控制信息双向流动)
- 使用有限状态机(FSM)来定义发送方和接收方
有限状态机概述
- 箭头:表示协议从一个状态变迁到另一个状态
- 横线上方:表示引起变迁的事件
- 横线下方:表示事件发生时所采取的动作
- ∧:表示没有事件或未采取动作
- 虚线:表示FSM的初始状态
构造可靠的的数据传输协议
rdt1.0 完全可靠信号的上的可靠数据传输
RDT1.0
条件假设
- 底层信道完全可靠:数据传送 不出错不丢失
- 收发双方速率匹配:接收方接受数据的速率和发送方发送数据一样快
- 所有分组都是从发送方流向接收方
- 接收方无需反馈信息,因为无差错发生
rdt1.0的FSM
接受发送方FSM相互独立
顺序 | 发送方 | 接收方 |
---|---|---|
事件 | 从上层接受数据rdt_send(data) | 从底层信道接收一个分组rdt_rcv(packet) |
活动 | 封装成分组make_pkt(data) | 解封取出数据extract(packet,data) |
将分组发送到信道中udt_send(packet) | 据传给上层deliver_data(data) |
rdt 2.X具有比特差错信道上的可靠的数据传输
RDT2.0 停止等待协议:发送方发完一个分组后停止,等待对方回答
条件假设
- 信道不完全可靠,可能产生比特差错,但不丢包
- 所有分组按序发送并被接收(有些bit可能出错)
肯定确认,否定确认
类比例:
- 打电话传递一条长信息
- 收听者:
听清每句话后说“OK”(肯定确认);
听到不清楚的话,要求对方重复说“请重复一遍”(否定确认)。
肯定确认:告诉发送方内容被正确接收。
否定确认:告诉发送方内容出错需要重传
基于重传机制的可靠数据传输协议称为自动重传请求协议ARQ(Automatic Repeat request)
ARQ协议处理比特差错机制
差错检测
使接收方检测出是否出现比特差错。
- 如采用差错检测和纠错技术,使接收方能够进行差错检测并纠正。
- 需要给分组附加额外的比特一起发送。如rdt2.0协议,分组增加检验和checksum字段。
接收方反馈
使发送方知道发送的分组是否被正确接收。
- 通过接收方回送肯定确认(ACK)和否定确认(NAK) 分组完成。
- 如rdt2.0协议,接收方将向发送方回送*ACK(“1”比特)或NAK(“0”比特)*分组。
重传
接收方收到有差错的分组时,通知发送方重传该分组。
rdt2.0特点
- 可以解决数据分组出错问题。
- 若返回ACK或NAK分组受损,发送方无法知道接收方是否正确接收了上一块数据。
rdt2.0的FSM
停等(stop-and-wait)协议:发送方发完一个分组后停止,等待对方回答。
基本模型
顺序 | 发送方 | 接收方 | |||
---|---|---|---|---|---|
等待上层调用 | 等待上层数据 | 从底层接收一个分组 检查校验和 | |||
事件 | 层数据传来rdt_send(data) | 分组出错 | 事件 | rdt_rcv(rcvpkt) && corrupt(rcvpkt) | |
活动 | 计算校验和,封装成分组make_pkt(data,checksum) | 活动 | 丢弃分组 | ||
发送分组udt_send(sndpkt) | 返回NAK 分组udt_send(NAK) | ||||
收到ACK分组 | 事件 | rdt_rcv(rcvpkt) && is ACK(rcvpkt) | 分组无错 | 事件 | 收到分组且无错误rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) |
活动 | 返回初始状态 | 活动 | 从分组中取出数据extract(rcvpkt,data) | ||
收到NAK分组 | 事件 | rdt_rcv(rcvpkt) && is NAK(rcvpkt) | 将数据传给上层deliver_data(data) | ||
活动 | 重传上次发送的分组udt_send(sndpkt) | 返回ACK 分组udt_send(ACK) | |||
等待ACK或NAK |
- 当发送方在等待ACK或NAK状态时,不能从上层得到数据,直到收到ACK离开该状态。
- 发送方在收到ACK分组之前,不会发送任何新数据,直到收到ACK分组为止。
无错误场景
有错误场景
处理受损ACK和NAK的可能方法
收发双方互不理解对方回答的含义使对话不能正常进行。
-
增加足够的检验和比特:
使接收方不仅可以检测差错,还可进行恢复。适用于会产生差错但不丢失分组的信道。
-
当发送方收到含糊不清的ACK或NAK分组时:简单地重发当前数据分组。
产生冗余分组(duplicate packets):同一个分组收到两次。接收方无法知道收到的是新的分组还是重传的分组。
冗余分组解决方法
给分组添加一个序号字段。
-
发送方:给发送的数据分组编号,并将其序号放入“序号字段”。
每发送一个新的分组*“序号加1”。*
-
接收方:通过检查序号,确定收到的分组是不是重复传送。
按序号接收,若本次接收到的分组序号与前一次收到的分组的序号相同,即为重复分组,将该重复分组丢弃。
序号位数选择
停等协议:只需用一个比特,即“0”和“1”两种不同的序号。
序号通过模2运算向前移动,可以区分前后相邻的两帧。0、1、0、1、……
说明
-
ACK和NAK分组不需要指明要确认的序号。因为假设信道不丢失分组。
不丢失必然有序,故此ack,nak天然带序号
-
发送方知道所接收的ACK和NAK分组是对最近发送分组的响应。
rdt2.1
可以处理重复分组
判断分组是否重复方法:当前所处状态提供了期望收到分组的的序列号
相较rdt2.0多了序列号
- 指出正发送或准备接收的分组的序号。
- 发送或期望接收0号分组的状态中的动作与发送或期望接收1号分组的状态中的动作相似,只是序号处理方法不同。
- 使用从接收方到发送方的肯定和否定确认。
发送方
接收方
发送方 | 接收方 |
---|---|
上层取数;发0# 分组 | 收到受损的分组:丢弃,并回发一个否定确认(NAK ) |
收到错误分组或NAK;发0# 分组 | 收到乱序的分组:是重复分组,丢弃,并回发一个肯定确认( ACK ) 。 |
收到ACK; | |
上层取数发1# 分组 | |
收到错误分组或NAK;重发1# | |
收到ACK |
- 对收到0或1且内容正确,必发ack,因为收到正确内容则可以继续接收下一个数据
rdt2.1 vs rdt2.0 | |
---|---|
发送方 | 接收方 |
每个分组增加了序列号 | 需判断分组是否重复 当前所处转股管态提供了期望收到分组的序列号 |
两个序列号(0,1)够用,采用平等协议,收到的内容正确的皆可用于数据 | 接收方无法知道ACK/NAK是否被发送方正确收到 |
状态数量翻倍;状态必须记住当前的分组序列号 |
rdt2.2
无NAK消息协议;给ACK标记序列号
- 接收方通过ACK告知最后一个被正确接收的分组
- 在ACK消息中显示地加入被确认分组的序列号
- 发送方收到重复ACK之后,采取与收到NAK消息相同的动作重传当前分组
发送方
接收方
rdt3.0 具有比特差错的丢包信道上的可靠的数据传输
保证可靠数据传输协议的要点:检验和、序号、定时器、重传、肯定和否定确认。
假设条件
- 会出现比特差错
- 会出现丢包
- 发送的的数据分组丢失
- 或接收方回发的AKC丢失
发送方发现丢包处理方法
发送方等待合理时间
-
若未收到ACK,重传
-
若分组或ACK只是延迟而非丢失
- 重传产生重复,序列号机制能够处理
- 接收方需在ACK中显式告知所确认的分组
-
需要定时器
设置一个“递减(倒)计数定时器”,给定时间过期后,中断发送方。
要求发送方:
- 每发送一个分组(包括第一次和重发的分组),启动一个定时器;
- 响应定时器中断:采取适当的动作;
- 终止定时器。
rdt3.0的FAM
发送方
接收方
rdt3.0接工作场景
无差错与分组丢失
ACK丢失与过早超时
停止-等待协议流程
基本概念
-
N(S):发送序号变量,当前传送分组的编号,发送新分组时,N (S)+1;
-
V®:接收序号变量,当前准备(希望)接收的分组序号,每收到一个新分组时,V®+1;
-
判断重复分组(接收方):
N(S) = V®,收到的是新数据分组;
N(S) != V®,收到的是重复分组。
发送方和接收方流程
发送方
接收方
停等协议效率
能够正常工作,但效率不高。
发送方(信道)利用率Usender = 发送方将比特发送到信道的时间/发送时间 即(传输时延L/R/发送方从发送分组开始,到收到对方ACK分组,所需的时间。)
- 两个端系统之间的光速往返传播时延RTT约 30ms
- 信道传输速率 R=1Gb/s(109bit/s)
- 分组长 L = 1000字节
- 发送方只有0.027%的时间忙。
- 发送方在30.008ms内只能发送l000byte,有效的吞吐量仅为267kbit/s(l000X8/(30.008X10-3),即使有1Gbit/s的链路可用)
流水线技术改进效率
允许发送方连续发送多个分组而无需等待确认,称为流水线技术(众多分组可看成是填充到一条流水线中)。
N为连续发送分组个数
应用实例
技术要点
- 增加序号范围:由于可连续发送多个分组,每个分组有唯一序号,可能有多个在传输中的未确认报文。
- 需要缓存多个分组:
发送方至少能缓冲已发送但没有确认的分组;
接收方缓存已正确接收的分组。 - 序号范围和对缓存的要求:取决于数据传输协议处理丢失、差错及过度延时分组的方式。
滑动窗口协议(Silding-window protocol)
窗口:
- 允许使用的序列号范围
- 窗口尺寸为N:最多有N个等待确认的消息
滑动窗口:
- 随着协议的运行,窗口在序列号空间内向前滑动
主要类型:GBN,SR
GBN协议
回退N步 (Go-Back-N, GBN协议)
GBN协议综合可靠数据传输的全部技术:使用序号、累积确认、检验和以及超时/重传操作等
GBN缺点:可能需要很多的重传
基本思想
发送方:连续发送多个数据分组,停止等待
- 收到确认ACK,继续发送后面分组;
- 超时,未收到应答,从出错分组开始重发
接收方:按序号接收数据分组
- 正确:接收处理,发确认ACK;
- 出错:将出错分组及后面分组均丢弃,不发任何应答。
注意事项
- 连续发送的分组个数不能太多:
增加序号字段位数;
出错时,要重传很多数据分组,影响效率。 - 连发个数受流水线中未确认的分组数限制,不能超过最大允许数N。
通过设置发送窗口和接收窗口来分别控制连续发送和接收的分组个数。
发送方
控制发送方连续发送的个数
实际是允许连续发送的序号表,只有落在发送窗口所包含序号之内的,才能不等待应答发送。
-
分组头部包含k-bit序列号
-
窗口尺寸为N,最多允许N个分组为确认
-
ACK(n):确认序列号n(包含n)的分组均已被正确接收 累计确认
可能收到重复ACK
-
为空中的分组设置计时器(timer)
超时Timeout(n)事件:重传序列号大于等于n,还未收到ACK的所有分组
序号范围分割成4部分:
- [0,base-1]:已经发送并确认过的分组。
- [base,nextseqnum-1]:已经发送但未被确认分组
- [nextseqnum,base+N-1]:用于将立即发送的分组
- [base+N, ]不能使用,直到当前流水线中未被确认的分组得到确认(序号为base的分组)。
发送窗口大小WT
- WT = N,即序号范围[base,base+N-1],包括已发送未被确认的分组、以及准备发送的分组。
- 随着协议的运行,发送的分组陆续被确认,发送窗口在序号空间内向前滑动。
- 若分组序号字段的位数是k,则序号范围是[0,2k-1]
发送方扩展FSM
响应的事件:
-
上层的调用:上层调用rdt_send()检查发送窗口是否已满(是否有N个已发送、但未被确认的分组)
窗口未满:创建一个分组并将其发送,更新变量
窗口已满:将数据返回给上层,以后再试。 -
收到ACK: 对序号为 n的分组的确认使用累积确认,即表明接收方已正确接收到序号为n及以前的所有分组(从接收方来说,如果n分组以前有一个分组没有正确收到,接收方是不会发出n分组的确认的;所以发送方只要收到n的确认即说明n及以前分组接收方都正确收到了,但是发送方不一定能收到所有n及以前分组的确认,因为有些确认分组可能丢掉了)。
-
超时:设置定时器处理*“数据或确认分组丢失”*情况
只使用一个定时器,作为最早的已发送但未被确认的分组的定时(每次窗口滑动后,还有已发
未确认分组时,定时器都重新开始对窗口中基序号分组进行倒计时,即基序号变化且还有已发未确认分组时将重启定时器)。
产生超时:发送方重发所有已发未确认分组。
收到一个ACK: 仍有已发送但未被确认的分组,重新启动定时器。
没有未确认报文,终止定时器。
接收方
按序接收。接收方WR=1。
- 正确按顺序接收到序号为n 的分组:将分组中的数据交付到上层,并回发一个 ACK;
- 分组一次性交付给上层:分组k 被交付, k之前均已交付。
- 其他情况的分组:丢弃该分组,并为最近按序接收的分组重发ACK。
- 丢弃所有失序分组:控制简单,接收方不需要缓存任何失序分组。
接收方扩展FSM
ACK机制: 发送拥有最高序列号的、已被正确接收的分组的ACK
- 可能产生重复ACK
- 只需要记住唯一的expectedseqnum
乱序到达的分组:
- 直接丢弃->接收方没有缓存
- 重新确认序列号最大的、按序到达的分组
- 接收方维护下一个按序接收的分组的序号,该值保存expectedseqnum变量中。
窗口为4的GBN协议的运行
-
发送方:连续发送4个分组后等待,直到一个或多个分组被确认;
每接收到一个连续的ACK时,该窗口便向前滑动。
-
接收方:收到一个连续的正确的分组,窗口向前滑动。
SR协议
选择性重传 (Selective Repeat, SR协议)
发送方只重传出错(丢失或受损)的分组。
SR协议的发送方和接收方窗口不总一致
基本概念
GBN需要重传很多分组
发送方:连发多个数据分组,停止等待
- 收到确认ACK,继续发送后面分组;
- 超时,未收到应答,只重发出错分组。
接收方:不按序号接收数据分组
- 正确:接收、按顺序交付,发确认ACK;
- 出错:丢弃该分组,以后正确分组放入缓存,当出错分组正确收到后,按顺序一起交付。
不按序接收。接收窗口大小 > 1,即只要序号落在接收窗口内的正确分组都可接收。
某时刻发送方/接收方窗口
发送方的事件与动作
事件 | 动作 |
---|---|
从上层收到数据:当从上层接收到数据后,发送方检查下一个可用于该分组的序号。 | 若序号在发送方窗口内,则将数据打包并发送 |
否则:与GBN一样,将数据缓存,或将其返回给上层,以后再传。 | |
超时:每个分组有自己的定时器,超时后只能发送一个分组。 | |
收到ACK:将被确认的分组标记为*已接收(*若该分组序号在窗口内)。 | 如果该分组的序号等于发送基序号send_base,则窗口基序号向前移动到具最小序号的未确认分组处。 |
窗口移动后,仍有序号落在窗口内的未发送分组,继续发送。 |
接收方的事件与动作
接收方接收正确分组不管其是否有序。
事件 | 动作 |
---|---|
失序分组: | 先被缓存,直到所有丢失分组(序号更小的分组)被收到为止,才可将一批分组按序交付给上层。 |
序号在接收窗口内的分组被正确接收:收到的分组落在*[rcv_base,rcv_base+N-1]内,接收并回发一个ACK。* | 该分组以前没收到过:被缓存; |
该分组的序号等于接收基序号:则该分组及已缓存的序号连续的分组交付(起始于基序号)给上层。接收窗口按交付的分组数量向前移动。 | |
收到序号在接收基序号以前的分组: | 该分组是接收方以前已确认过的分组。生成一个ACK, 并回发给发送方。 如果接收方不确认,发送方窗口不能向前滑动。 |
其他情况: | 忽略该分组。 |
SR协议示例
窗口最大尺寸
若序号位数k位,SR协议,发送窗口和接收窗口尺寸最大是2k-1,不是2k-1。即序号空间一半。
避免发生接收序号重叠,出现重复分组
反例说明:
设序号2位,则序号空间为0#~3#,发送窗口和接收窗口尺寸最大是2,不是3。
三种协议比较
可靠传输机制及用途总结
机制
-
校验和:检测分组传输中的比特错误。
-
定时器:用于检测分组超时及重传分组
分组或ACK丢失;
一个分组被延时但未丢失(过早超时),或ACK丢失,接收方可能会收到重复分组。 -
序号:发送的数据分组按顺序编号。
接收方可检测分组丢失(序号间的空隙)或重复(相同序号的分组)。 -
**ACK确认:**接收方用其告诉发送方某个分组或一组分组已被正确地接收。
确认报文包含被确认的分组或多个分组的序号。可以是逐个的或累计。 -
**NAK否认:**接收方告诉发送方某个分组尚未正确地接收。包含未被正确接收的分组的序号。
-
*窗口、流水线:*发送方可以连续发送序号落在发送窗口序号范围内的分组,可以不用逐个确认。
问题
-
即使发送方或接收方的窗口中都没有包含x,但可能会出现一个具有序号或确认号x的分组的旧拷贝。
-
为确保序号不被重新使用,需要*发送方“确信”*任何先前发送的序号为x的分组都不再在网络中为止。
-
*规定分组最长的寿命:*分组在网络中“生存”的时间不会超过某个固定的最长时间。
如在TCP中假定为大约3分钟。