计算机网络基础 (十七)--- 传输层 -TCP 的可靠传输
文章内容概览
建议结合我的上一篇文章来看本篇内容:可靠传输的基本原理
TCP协议的可靠传输
TCP的可靠传输是基于连续ARQ协议的(关于ARQ协议,可以看我的上一篇文章)
ARQ协议中有两个重要的概念:滑动窗口和*累计确认*。这两个概念在TCP的可靠传输中同样适用
TCP的滑动窗口以字节为单位
假设有一段的字节流需要传输,滑动窗口的大小为7,这里是为了方便理解,所以窗口设的很小,实际情况下的窗口是很大的。窗口中的7个字节表示都是可以传输的,窗口左边的是已经确认的字节序号,窗口右边的是不允许发送的字节序号。图中的23表示的就是对方期待接收到的下一个字节,其实也就是TCP首部中的确认号的概念
假如在某一个时刻23~26这四个字节已经发送出去了,但是没有收到确认信息,这个就属于已发送但未确认的字节。而窗口中剩下的三个字节就属于可用窗口,也就是后边三个字节是可以发送的。但是,因为发送出去的四个字节还没有收到确认,所以窗口还不能向后移动。假设经过一段时间之后,收到了23、24这两个字节的确认信息,此时就可以将窗口向后移动两个字节
假设窗口中的7个字节都已经发送出去了,但是一个确认信息都没有收到,此时可用的窗口是0,因为窗口中所有发送的字节都没有收到确认,这个时候,滑动窗口不能向后推进。这是实际可能存在的情况
假设窗口中的7个字节都已经发送出去了,在某一个时刻,收到了25和27这两个字节的确认信息。可以发现,这种情况,确认信息并不是按窗口中字节的顺序收到的,此时该怎么办?
首先可以知道的是,23、24这两个字节的确认信息是没有收到的,因此,窗口是不能往前推动的。假设现在超时时间已经到了,而23、24还没有收到确认消息,此时会怎么办?这种情况下,即使25、27这两个字节的确认信息已经收到了,但是,此时还是会从23开始重传消息,因为23、24的确认信息还没有收到。因此,超时之后,会从23开始重发消息,即使收到了后边字节的确认消息也没有用,这个就属于TCP协议的可靠传输
从上边可以知道,如果窗口中的字节没有按序收到确认信息,那么超时之后就会对窗口中的字节进行重新发送。由此也可以看到,TCP的这种可靠传输,效率并不是很高,因为已经收到了25、27这两个字节的确认信息,意思就是这两个字节是准确的到达了接收方的,但是由于23、24这两个前边的字节没有收到确认信息,超时之后,还是需要对25、27进行传输,这样就导致可重传的效率并不高。有没有办法可以提高这个效率?
选择重传
选择重传,顾名思义,就是可以选择一部分消息进行重传,而不是将窗口中所有的消息进行重新传输
选择重传是如何进行工作的?
选择重传需要指定需要重传的字节
每一个字节都有唯一的32位序号(这个在TCP首部中,选择重传会指定这个32位序号是什么)
(建议在看后边的内容之前,回看一遍TCP头部的内容,这样理解下边内容会更加的容易)
对于TCP首部,其实我们知道它并没有存储选择重传指定字节的位置。每一个字节都有一个唯一的序号,所以在存储需要选择重传的字节的序号时,也是需要耗费很多的空间的。因此,在实际的选择重传中,这个数据实际上是存储在TCP选项中的
在TCP协议详解的文章中有进行过简单的计算,知道了TCP选项最多有40个字节。因为一个序号是占用4个字节,那也就是说,TCP选项中最多可以放10个序号。那是不是表示,选择重传只能重传10个字节?
其实并不是的,在了解TCP的时候知道,TCP的报文,一次是可以传输很多个字节的,前边的例子主要是为了方便对TCP可靠传输进行理解,才把每次可以传输的字节数设置的很少。对于实际的TCP传输,它一次可以传输上百或上千个字节
因此,这里边的序号并不是说选择指定某一个字节的。因为,如果发生出错了,很可能整个TCP报文都丢失了,这种情况其实就连续的丢掉一段的字节,因此,这里的选择重传,更多的情况是对一段字节来进行重传的。所以这个时候序号所表达的意思,一般都是需要重传的边界
看个例子,假设要传送1000~3500这么多字节的数据,把500个字节看做是一个TCP报文。假设1000~1500范围字节的TCP报文丢失了,这个时候就可以指定两个边界,分别是1000和1500,将他们存储到TCP首部中的TCP选项中,表示1000~1500这么多个字节,都是需要重新传输的。因此,此时TCP选项中的1000和1500并不是指重传1000和1500这两个序号的字节,而是重传1000到1500这个范围中的所有字节
如果看完对你有帮助,辛苦给个三连鼓励一下哦!
版权声明: 本文为 InfoQ 作者【书旅】的原创文章。
原文链接:【http://xie.infoq.cn/article/9001b85270e990845b286ecb1】。文章转载请联系作者。
评论