UDP+构造可靠数据传输协议

文章详细介绍了如何通过UDP构造一系列可靠数据传输协议,从完全可靠的rdt1.0到处理比特差错的rdt2.0和rdt2.1,再到处理丢包的rdt3.0。rdt2.2实现了无NAK的可靠传输,而rdt3.0引入了数据定时器来应对丢包。接着讨论了流水线传输协议,包括回退N步(GBN)和选择重传(SR)协议,它们提高了传输效率并优化了错误处理机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

UDP

UDP报文结构如下所示:

由于源端口号以及目的端口号均为16位,因此端口号最多有655536个。

长度字段指示了UDP报文段中的字节数(首部加数据),因此主机可以通过该字段来判断出报文和报文之间的边界。

校验和用来判断传输的数据是否出现了差错。

在这里插入图片描述

构造可靠数据传输协议

完全可靠信道的可靠数据传输:rdt1.0

首先,最简单的情况即底层信道是完全可靠的,该协议未rdt1.0,rdt的发送端只要接受高层的数据,然后发送给接收端即可。而rdt的接收端也只要将接收到的数据传给高层即可。
在这里插入图片描述

经具有比特差错信道的可靠数据传输:rdt2.0

假设底层信道是会产生比特差错的,即传输的数据可能会出现错误。因此,协议必须要实现:(1)检测出差错;(2)接收方反馈是否出现错误;(3)发送方根据接收方的反馈确定是否要重传数据。

发送端若接受到NAK,则重发数据,若接收到ACK则等待上层调用准备发送下一个数据。

接收端则是判断接收到的数据是否出现错误,若出现错误发送NAK给发送端,反之发送ACK给发送端。
在这里插入图片描述

rdt2.0看起来可以运行了,但它存在一个致命缺陷,即没有考虑到ACK或NAK分组受损的可能性。因此,首先需要对ACK/NAK添加检验和比特来检查出是否存在错误。此外,如果一个ACK/NAK受损,发送端将无法确定接收端是否正确地接收到数据。并且,还需要让接收端知道自己发送的ACK/NAK是否出现问题。

解决上述问题的一个简单方法是在发送的数据中添加一个新的字段,让发送发对其数据进行编号。对于该协议,使用1比特序号,即序号只有0,1,这样可以让接收方知道发送方是否正在重传前一个发送分组,通过这种方式告知了接收端发送端ACK/NAK出现了问题。于是便有了rdt2.1。

发送端一开始发送0序号的数据,如果接受到发送端发到的NAK,或者ACK/NAK出现错误,则重发数据。如果接收到的ACK/NAK没有出现错误,并且接收到的是ACK,则准备发送1序号的数据,即下一条数据。

发送端开始发送1序号的数据,与0序号相同,如果收到NAK或ACK/NAK出现错误,则重发数据。无错并且是ACK,则准备发送0序号的数据。

接收端一开始准备接收0序号的数据,(1)若数据出现错误则发送NAK给发送方。(2)若数据没有出现错误,但发现接收到的是1序号的数据,则发送ACK给发送方,并且继续等待0序号的数据。这里之所以会接收到1序号的数据是因为接收端在接收到1序号数据后发送ACK给发送方,便转为“等待接收0号数据”的状态。而ACK是可能出现错误的,当出现错误时,发送方为了保险起见,会再将1序号的数据发送给接收端,这时接收端便知道自己发送的ACK出现的错误,只要再发送一次即可。而NAK出现错误的话,因为本身就在等待该序号的数据,所以等待发送方再次发送即可。(3)若数据没有出现错误并且接受到的是0号数据,便发送ACK给发送方,并且准备接收1序号的数据。对于1序号的数据处理方式和0序号相同。

在这里插入图片描述

在这里插入图片描述

协议rdt2.1使用了从接收方到发送方的肯定确认和否定确认。如果不发送NAK,而是对上次正确接收的分组发一个ACK,也能实现NAK一样的效果。发送方如果接受到对同一个分组的两个ACK便可以知道接收方没有正确接收到被确认两次分组后面的分组。rdt2.2是在有比特差错信道上实现的一个无NAK的可靠数据传输协议。

在这里插入图片描述

rdt2.2与rdt2.1的差别在于,ACK需要包含序号,对上一分组序号的ACK被看做为NAK。

经具有比特差错的丢包信道的可靠数据传输:rdt3.0

现在假定除了比特受损外,底层信道还会丢包。如果发送方在一个时间段内没有收到ACK,则认为丢包,重传分组。

发送方在发送每个数据包时,都会开启一个数据定时器,与rdt2.2处理发送方返回的信息不同的事,如果接收到错误的数据或是接收到错误序号的ACK时,什么都不做,而是等到定时器结束时再重传。这是因为发送方发送了一个数据包之后可能因为超时(没有接收到接收方的任何信息)又发送了一个数据包,此时如果接收方恰好将第一个数据包的反馈送到了发送方并且出现了错误,发送方可以继续等待第二个相同数据包的反馈,而不是立刻再发送一个相同的数据包。当发送方接收到正确的反馈后,将停止计时器。

在这里插入图片描述

流水线可靠数据传输协议

由于rdt3.0本质是一个停止等待协议,在收到接收方的反馈之前,只能发送一个数据,这就导致了其效率很低。因此出现了回退N步(GBN)和选择重传(SR)这种流水线传输协议。

回退N步

在回退N步协议中,允许发送方发送多个分组而不需等待确认,但其发送的分组数不能超过某个最大值N。

GBN将基序号定义为最早未确认分组的序号,将下一序号定义为最小的未使用序号(允许发送但还未发送)。通过序号将整个缓冲区分为4部分,在 [ 0 , b a s e − 1 ] [0,base-1] [0,base1]部分中为已发送并被确认的分组。 [ b a s e , n e x t s e q n u m − 1 ] [base,nextseqnum-1] [base,nextseqnum1]为已发送但未确认的分组。 [ n e x t s e q n u m , b a s e + N − 1 ] [nextseqnum,base+N-1] [nextseqnum,base+N1]为可以发送但未发送的分组。大于或等于base+N-1的序号是不能用的,直到流水线中未被确认的分组被确认位置。
在这里插入图片描述

对GBN发送方来说,当上层要求传输层即GBN发送数据时,会先检查发送窗口是否已满,如果未满则产生一个分组并发送,如果发送的数组恰好是第一个已发送还未确认的分组,则开启定时器。如果窗口已满,则将数据放入到缓冲区中。

当GBN发送方收到一个ACK时,是对序号为n的分组的累计确认,即表明接收方已经正确地收到序号为n以及之前的所有分组。每当GBN发送方接收到一个ACK,便将base向前调整,如果所有分组都被确认了则停止计时器,反之则对最开始的发送分组开启一个定时器。总的来说,如果收到一个ACK,但仍有已发送但未被确认的分组,则定时器重新启动。如果没有已发送但未被确认的分组,停止该定时器。

当GBN发送方的定时器超时时,则重发所有已发送但未被确认的分组。

在这里插入图片描述

对于GBN接收方来说,其会一直维护一个应该接收的分组序号变量expectedseqnum,即当前应该接收的分组序号。如果发送方的序号大于接收方应接受的序号,则会对前一个包做出确认表示未正确收到。如果接收到的序号为n并且恰好等于expectedseqnum,则接收方接收该数据,并将ACK+确认序号发送给发送方。

在这里插入图片描述

可以看出,在GBN中,接收方会丢弃所有的失序分组。丢弃一个正确接收的分组将会导致随后对该分组的重传会出错,因此甚至需要更多的重传。

下图为窗口长度为4的GBN协议运行情况。开始的0和1分组正确到达接收方,分组2丢失,分组3正确到达接收方。因此,接收方接收到0和1的ACK后,可以将base向前移动2,并发送分组4和5。但因为分组2没有到达接收方,所以分组3,4,5都会被接收方丢弃。等到定时器超时,发送方继续发送分组2,3,4,5。

在这里插入图片描述

选择重传

选择重传(SR)通过让发送方仅重传那些它怀疑出错的分组可以避免不必要的重传。与GBN不同的是,发送方可以不按顺序接收窗口中某些分组的ACK。
在这里插入图片描述

对于SR发送方来说,当从上层接收到数据后,SR发送方检查下一个可用于该分组的序号。如果序号在窗口内,则发送,否则就进行缓存。

当SR发送方每发送一个分组,都会对该分组添加一个定时器。

当SR发送方收到ACK时,如果ACK的序号在窗口内,则将对应的分组标记为已接收并取消定时器。如果收到的序号等于base,则base向前移动至具有最小序号的未确认分组处。然后由于窗口移动,SR发送方可以继续发送那些未发送的分组。

对于SR接收方来说,当序号在 [ r c v _ b a s e , r c v _ b a s e + N − 1 ] [rcv\_base,rcv\_base+N-1] [rcv_base,rcv_base+N1]时,即分组落入到接收方可接受的分组区域内,则直接发送对该分组的ACK。如果接收方没有接收到过该分组,则接收该分组。如果收到的分组的序号等于接收窗口的base,则接收方可以前移窗口,并将数据上交到应用层。

当序号在 [ r c v _ b a s e − N , r c v _ b a s e − 1 ] [rcv\_base-N,rcv\_base-1] [rcv_baseN,rcv_base1]时,即分组落入到base窗口之前,即已经上交过的数据区域内。接收方直接发送分组对应的ACK即可。

其它情况,直接忽略该分组。

在这里插入图片描述

当面对有限序号范围的事实时,窗口大小相对于序号空间大小较大时将会产生问题:

如下图所示,接收方成功接收到前三个分组,正在等待第4、5、6个分组,但发送方要重传0,1,2分组。这时接收方不能判断0分组时第一个分组,还是第4个分组。这是因为窗口相对于序号空间来说较大,当窗口前移一个窗口大小时,其实际上能够覆盖2倍窗口大小的序号值。因此窗口大小需要小于或等于一半的序号数。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值