为了更好地学习TCP的可靠传输,首先介绍一些可靠传输的基本原理。这里不仅仅会涉及可靠传输,还会涉及流量控制和拥塞控制的一些基本原理。
可靠传输最基本的操作就是:传丢了或者传递出错了就重传,直到正确接收。如何发现传输错误并予以恰当的重传,这是可靠传输要解决的最基本问题。可靠传输的这个基本操作可以通过为数据编号和发送接收确认来实现。
(1)数据编号。网络传输难免会发生丢包(错包也可以视为特定形式的丢包)或者乱序的现象。不采取应对措施时,丢包、错包与乱序到达,在接收端是无法发现的。为数据进行编号,首先,可以让接收端能够发现数据传输中的问题。其次,接收端接收到数据后,可以依据数据的编号重新排列数据,从而纠正乱序;同时,接收端也可以根据排列好的数据中缺哪些数据,发现哪些数据没有被正确传输过来。为数据进行编号,首先可以让接收端解决乱序问题,其次还可以让接收端发现传输中丢掉的或者出错的是哪些数据。
(2)发送接收确认。传输发生了问题,就要进行重传,直到正确接收。前文介绍过,丢包、错包的问题是由接收端发现的,一种当然的想法就是接收端把发现的问题通知接收端。数据传输正确时,接收端只需要闷头接收,一旦发现有丢包、错包,接收端便通知发送端。发送端接到通知后重传对应的数据就可以了,但是,如果接收方的重传请求也丢失了怎么办?综合来说,这种“闷头接收,有问题发送重传请求”并非一种好的解决方案。
关于这个问题,可以换一个角度来解释。因为最终采取重传行动的是发送方,所以,从发送方角度考虑问题更合适。发送方总要关心这样的问题:我刚刚发送出去的数据,需要重新再发送一遍吗?因此,让接收方每次正确接收到一个数据包后应答“刚才××编号的数据我正确收到了,请放心”这样更为合适。这便是接收确认。收到接收确认信息之后,发送方就可以确认此份数据被正确传输了。图5-4所示为接收确认示意。
图5-4 接收确认示意
采用“接收确认”,而不采用类似“出错报告”的形式,更有利于解决“是否重传”的判断。在实际的操作过程中,接收方只需要对正确接收的数据发送“接收确认”即可,对于丢包、错包都可以不予理会,只待发送方重传,而发送方采取的策略则是:一份数据发送出去后,若等待了足够长的时间(相对于信息往返时间)还没有收到接收确认,就认为没有正确接收,就需要重新传递一份数据。
刚刚提到了时间问题,就是发送方在发送数据后认为需要重新传递这份数据而等待的时间。恰当的设置这个时间的长短很重要。过短,可能让本来能到达的确认被视为超时,从而会让不必要的重传多次发生;过长,会让双方多一些不必要的等待。无论是哪种情况,都会降低通信的效率。关于超时时间的设置,是后面学习TCP的核心关键问题之一。
图5-5所示为发送方没有收到接收确认的几种情况。造成发送方没收到接收确认,可能是数据包出现了问题,也可能是确认包出现了问题。当这些情况发生,就会造成超时重传现象的发生。图5-5(a)描述了数据包出现问题的情况,由于没有收到数据,接收方没有任何确认应答,发送方超时重传,待接收方正确接收后发送确认;图5-5(b)描述了确认包丢失的情况,发送方超时重传,接收方对重复接收的数据不需要处理,但需要再次发送接收确认;图5-5(c)描述了网络突发状况导致确认信息延迟,造成了发送方超时重传。对于第二份到达数据,发送方丢弃数据,再次确认收到,而发送方收到两份确认信息时,也无需再处理。
前文介绍的接收确认都是对数据包逐一确认的。在实际协议中还可以采用另外一种“积累确认”的处理方式。所谓“积累确认”,是指接收方向发送方表示“××编号之前的数据,我全部正确接收到了”。这样,在一些场合下,可以减少确认数据包的传输数量。
通过对数据编号、接收确认和超时重传,我们保证了最基本的可靠传输。而可靠传输也具有不同的处理方式。基本的处理方式可以列为这样3种:停止等待、流水线传输和滑动窗口。接下来我们简单介绍一下这3种方式的基本原理。
图5-5 发送方没有收到接收确认的情况示意(www.xing528.com)
(1)停止等待方式是指发送端在收到确认信息之前,不发送下一个信息。在等待的过程中可能等来超时重传操作。我们前面在做基本原理介绍时,采用的其实就是这种方式。图5-4、图5-5都示意了这种处理方式。停止等待方式的问题在于它的通信效率比较低。设备长期处于等待对方回应的状态,在绝大多数的时间里,信道也都处于空闲状态。
(2)为了提高传输的效率,发送方可以采用流水线传输。流水线传输就是发送方可以连续地发送多个分组。一个数据分组发送出去后,马上发送下一个分组,不必等待接收确认。这样信道上一直有数据不断地在传输,可以保证信道有很高的利用率。如果正确传输的话,那么接收确认总会来的。流水线处理方式示意如图5-6所示。这种传输方式的信道利用率虽然高,但是不考虑接收方的接收能力,也不考虑网络的传输能力,实际上并没有谁在使用。
(3)在实际中,人们一般使用的是滑动窗口的处理方式。滑动窗口方式相对复杂,却是TCP的精髓之一。滑动窗口示意如图5-7所示。滑动窗口方式为发送方设置了发送窗口,只有在发送窗口内的数据方可被发送。当发送方收到接收确认之后,让发送窗口向前滑动,可以继续发送后续的数据。在发送窗口范围内的数据则以流水线方式发出,这样也保证了传输的速度和信道的利用率。窗口的大小,可以按照数据传输的需要而设置。如果将窗口大小设为1,此种方式退化为停止等待方式。如果将窗口大小设置为无穷大,此种方式变成纯流水方式。
在实际发送过程中,调整窗口的大小就可以控制发送的速度,就可以照顾到接收方的接收能力和网络的传输能力。这就意味着可以利用调整窗口大小的方法,在传输效率与传输能力间寻找平衡,这正是实际应用中所必然追求的,即前文所言的“TCP的精髓”。如何控制TCP发送窗口的大小,将是后面TCP讨论的另一个核心关键问题。
最后,还是回头看一下,在流水线传输情况下接收确认的问题。无论是否使用滑动窗口,只要涉及流水发送,发送方在发送完数据后,都要做下面这样一些操作。
首先,必然需要保留数据的一份副本,以备需要重新发送时使用;
图5-6 流水线处理方式示意
其次,需要为这一次发送开始计时。如果在计时达到某个阈值之前,发送方获得了接收方发回来的接收确认,就证明这份数据传输成功。如果某份数据超时,那么就需要重新发送。
所以,只要发送的窗口足够大,就会发生类似的情况:后面的数据正在排队被发送,中间会有若干要重新发送的数据来“加塞”。
图5-7 滑动窗口示意
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。