目录
之前在数据链路层时已经讨论过可靠传输(计网第三章(数据链路层)(二)(可靠传输)),也在其中提到过可靠传输并不局限于数据链路层。
一、基本概述
TCP通过以字节为单位的滑动窗口来实现可靠传输。
可靠传输的概念在之前已经提到过,这里不再做赘述。
在本篇博客中,假设网络不存在拥塞问题,即发送方的窗口值只由接收方的接收窗口确定。
二、具体实现
1.前后沿:
如图,发送窗口的边界可以定为前沿和后沿。后沿的后面部分是已经发送并收到确认的数据,可以从发送缓存中删除掉。前沿前面的部分是当前不允许发送的数据的序号。窗口内的是当前可以发送的数据的序号。
后沿移动情况有两种可能:
1.向前移动:收到了新的确认,就会向前移动。
2.不动:没有收到新的确认,就不会向前移动。
后沿不可能向后移动,因为不能撤销已收到的确认。
前沿的移动情况有三种:
1.不移动:(1)没有收到新的确认,并且对方通知的窗口值大小也没变。
(2)收到了新的确认,但是对方通知的窗口值恰巧缩小,所以没有移动。如图,假设接收方给发送方发回了11号确认,表示11号之前的数据全部收到。同时接收方将自己的窗口值改为2,那么发送窗口的前沿不会进行移动。也就是说,向前移动和向后回缩的尺寸恰好相等,就不会移动。
2.向前移动:一般都是不断向前移动,收到新确认后并且返回的接收窗口值不变或者增加都会向前移动。还是最开始的例子,收到11号确认后,接收窗口的值并没有改变,所以前沿移动到14号数据前。
3.向后移动:
向前移动的尺寸小于向后回缩的尺寸。 仍然用最开始的例子,假设收到11号确认后,接收方的窗口值变为了1,那么发送窗口的前沿反而从12变成了11。但是,这种情况很糟糕,比如在收到11号确认分组前,12号数据已经发送出去了,这时候又缩小窗口值不让发送,就会引发错误。所以并不支持这样做。
2.利用指针描述发送窗口的状态
如图:
实际p1指针就是窗口前沿的位置,p3指针就是窗口后沿的位置。
所以p3之后的部分仍然是已经给您发送并确认的数据的序号。
p1之前的部分是当前不允许发送的数据的序号。
p1-p3是发送窗口的尺寸。
p2-p3是已经发送但是还未收到确认的数据的字节数。
p1-p2是当前允许但还未发送的数据的字节数。
可以看到,实际上这种描述方法就是把发送窗口里的情况进行了更细致的分析。
3.有差错情况
如图:假设现在发送方向接收方发送了9到11号数据,但是9号数据在传输过程中丢失。接收方接收到后发现是未按序到达的数据,于是将10号和11号数据存入接收缓存中,并返回当前按序到达的最高序号的确认,确认号应该为9,表示9号之前的数据都已经正确接收。
在前面总结拥塞控制(计网第五章(运输层)(五)(TCP拥塞控制))时,提到了快重传算法,即发送方收到三个重复确认,就立即重传相应的报文段。在本例中,发送方只收到了一个重复确认,所以不会有所动作。
可能有些同学会问,为什么得三个重复确认?一个不行吗?
拿本例来说,实际上,接收方没有收到9号数据不一定就是9号数据丢失,也可能是停留在网络的某处,即数据未按序到达。如果在接收方返回确认之后,该数据又到达接收方,那么接收方就会将其放入接收缓存,现在接收方就可以将9、10、11号数据交付给上层。所以实际三个重复确认是为了确保该数据是真的丢失了。
注意:TCP的接收方要求必须有累计确认和捎带确认的机制,这样可以减少传输的开销。
可能有些读者看完TCP的可靠传输后,感觉好像TCP可靠传输就是选择重传协议。但是注意TCP的可靠传输的接收方是有累积确认的,但是选择重传为了只重传出现误码的数据分组,不再使用累积确认。TCP协议的设计目标是实现高效、可靠的数据传输,而不仅仅是仅重传出现误码的数据段。
所以TCP的可靠传输是有选择重传的机制,但是不仅仅局限于该机制,所以TCP协议的可靠传输并不完全等同于选择重传协议。