四块内容:停等协议、流水线协议、回退N步、选择重传。
从停等协议的问题,引入了流水线技术解决方案,而回退N步和选择重传则是针对流水线差错恢复的两种基本方法。
一、可靠数据传输(Reliable data transfer),提供给上层实体的服务抽象是,数据可以通过一条可靠的信道进行传输。不过由于下层协议不一定可靠,所以就有问题要处理。
下文仅讨论单向数据传输(unidirectional data transfer)的情况,即数据传输时从发送方到接收方的。
二、停等(stop-and-wait )协议:
首先,理解下ACK和NAK:肯定确认(positive acknowledgment)与否定确认(negative acknowledgment)。是接收方反馈信息的两种方式。
其次,是ARQ(Automatic Repeat reQuest自动重传请求)协议,简单理解为发送方发送数据,然后等待接收方反馈,然后再相应发送数据。
综合起来理解,就是发送方发送数据,然后等待接收方通过ACK或者NAK反馈,就是停等协议的大概流程。
但是会出现问题:比如说ACK或NAK受损,导致超时可能出现冗余包发送等问题,需要序号来区分包(冗余包?新包?),对于停等协议,一比特序号空间就足够了。(因为每次只发送一个包,然后就停下来等,1比特可以标志2个包,就可以是区分超时发送包还是新包(在ACK返回受损的情况下,接收方不知道下面收到的包是重复冗余的,需要序号来区分))
接下里的优化有,校验和(差错处理)、序号、定时器(超时)、ACK和NAK等。
定时器,超时处理,对应着ARQ。至于定时器的长短设置也是要考虑的,在后面的窗口协议中会讨论到。
类似的,序号空间的问题也是需要思考,为什么这里1个比特就够了。
还有ACK和NAK具体是怎么确认的?可以ACK对应着当前的,也可以是期望接收的下一个包,看具体协议定义。
现在网卡的作风,只要检测到错误(通过差错检测)就把包给丢掉,所以会出现上面提到的丢失情况。(还有路由器排队等……也会丢包)
这里需要对停等协议的效率进行分析:
假设是一条1Gbps的物理链路,RTT为30ms,发送1KB的帧:
那么把分组发送到链路需要的时间为(1*8*10^3Bits)/(10^9bps)=0.000008s=8us
则利用率为(假设反馈帧极小,处理时间为0)(8us)/(8us + 30ms)= 0.00027
从中可以看出一般的停等协议利用率(发送方实际忙着将发送比特送进信道的那部分时间与发送时间之比)极低,吞吐量只有267kbps,相对于1Gbps的可用链路,这……
二、流水线协议(Pipelined protocols):
为了解决上面停等协议对资源的极其浪费问题引入了一个解决方案:允许发送方发送多个分组而无需等待确认。
如下图:
因为从发送方向接收方传输的众多分组可以被看成是填充到一条流水线中,故这种技术被称为流水线。流水线技术可对可靠数据传输协议带来如下影响:
1、必须增加序号范围,因为每个传输的分组(不计重传的)必须有一个唯一的序号,而且也许有多个在传输中的未确认的分组;
2、协议的发送方和接收方也许必须缓存多个分组,发送方最低限制应当能缓存那些已发送但没有确认的分组,接收方也许需要缓存那些已正确接收的分组;
3、所需序号范围和对缓冲的需求取决于数据传输协议处理丢失、损坏及过度延时分组的方式等。
解决流水线的差错恢复有两种基本方法:回退N步(Go-Back-N)和选择重传(selective repeat,SR)。
三、滑动窗口(sliding window)协议
抽象理解,发送方和接收方各有一个缓存数组。
发送方存放着:已发生且成功确认包序号、已发送未确认包序号 (已发送已确认包序号序号|已发送未确认包序号)*、未发送包序号;
接收方存放着:已接受包序号、正在接收包序号、未接收包序号。
其中,每个数组有个两个扫描指针,开头和结尾,一起向后扫描,两者形成一个窗口。故称为窗口协议。
一般说窗口长度是指发送方的窗口长度,既是len(已发送未确认包序号 (已发送已确认包序号序号|已发送未确认包序号)*),而接收方缓存数组对应GBN和SR都有不同表现,因为两者针对差错到达帧由不同的处理方式。
这里为什么需要设置一个窗口长度,原因很简单,就是因为流量控制,不能无限制的发送数据包。
嗯,绕回滑动窗口流程,就是发送方把窗口内的帧都发送出去,当且仅当最小的帧确认收到后,窗口往后滑动到最小未确认帧。而接收方处理,需要看具体协议。
四、回退N步
回退N步,接收方则是只接受最小的未接受帧,对错序到达帧,都丢弃。
从图中,可以看出,接收方的窗口大小可以为1……而当发送方的窗口大小为1的时候,就相当于是停等协议了。
在GBN协议中,对序号为n的分组的确认采取的是累计确认(cumulative acknowledgment)的方式,表明在接收方已确认接收到序号n以前(包括n在内)的所有组。
实际上,一个分组的序号承载在分组首部的一个固定长度的字段中。如果分组序号字段的比特数为k,那么序号空间是【0, 2^k - 1】。在一个有限的序号空间内,所有涉及序号的运算必须使用模2^k运算(即序号空间被认为是一个长度为2^k的环,其中序号2^k - 1紧接着序号0)
再实际上,TCP有一个32Bits的序号空间,其中的TCP序号是按字节流中的字节数技术而不是按分组计数的。
另外,窗口长度必须小于或等于序号空间的一半,这个考虑ACK丢失刚刚好超时重发的情况就可以得到了。
五、选择重传
GBN本身存在很大的性能问题,尤其是当窗口长度和带宽时延积累都很大……一个单个分组的差错就可能引起GBN重传大量分组,许多分组根本就不要重传。随着信道差错率的增加,流水线可能会被这些没有必要重传的分组填满。
顾名思义,SR协议通过让发送方仅重传那些它怀疑在接收方出错(即丢失或受损)的分组而避免了不必要的重传。SR这种个别的,按需的重传协议要求接收方逐个地确认正确接收方的分组。
SR接收方将确认一个正确接收的分组而不管其是否按序到达的。错序到达帧将会被缓存直到所有丢失帧(即序号更小的帧)都被接收到,这时才将这一批帧按序交付给上层。也就是接收窗口滑动过该帧序号。
引入NAK要求发送方重传分组帧。
在这里,需要考虑之前提到的问题,就是超时定时器需要设置多大?答案是要超过2个RTT。很容易理解,如果timeout小于2个RTT,那么序号为2的帧将被重发多一遍。
最后提下更进一步的优化,比如说:
捎带确认,就是将确认信息放置到数据帧中……
延迟确认,就是不马上反馈ACK,等待积累到一定时候,一次性发送回复……