TCP的成块数据流
目前建立在TCP协议上的网络协议特别多,有telnet,ssh,有ftp,有http等等。这些协议又可以根据数据吞吐量来大致分成两大类:
(1)交互数据类型,例如telnet,ssh,这种类型的协议在大多数情况下只是做小流量的数据交换,比如说按一下键盘,回显一些文字等等。
(2)数据成块类型,例如ftp,这种类型的协议要求TCP能尽量的运载数据,把数据的吞吐量做到最大,并尽可能的提高效率。针对这两种情况,TCP给出了两种不同的策略来进行数据传输。
本章介绍TCP所使用的被称为滑动窗口协议的另一种形式的流量控制方法。该协议允许发送方在停止并等待确认前可以连续发送多个分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输。
滑动窗口协议
TCP中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据。发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。
滑动窗口协议的基本原理就是在任意时刻,发送方都维持了一个连续的允许发送的帧的序号,称为发送窗口;同时,接收方也维持了一个连续的允许接收的帧的序号,称为接收窗口。发送窗口和接收窗口的序号的上下界不一定要一样,甚至大小也可以不同。发送方窗口内的序列号代表了那些已经被发送,但是还没有被确认的帧,或者是那些可以被发送的帧。
我们将字节从1到11进行标号,接收方通告的窗口称为提供的窗口,它覆盖了第4字节到第9字节的数据,且通告窗口大小为6。发送方计算接收者的可用窗口,以便确定有多少数据可以被立即发送。当接收方确认数据后,这个滑动窗口向右移动。窗口两个边沿的相向运动有以下3种情况:
- 在数据被发送和确认时,窗口左边沿向右边沿靠近,称为窗口合拢。
- 在另一端接收进程读取已经确认的数据并释放了TCP接收缓存时,窗口右边沿向右移动,称为窗口张开,此时允许发送更多的数据。
- 当右边沿向左移动时,称为窗口收缩。这种方式不被建议。
3种情况如下图所示:
如果左边沿到达右边沿,则称为0窗口,此时发送方不能发送任何数据。
如果左边沿到达右边沿,则称其为一个0窗口,此时发送方一般不能再发送数据报,但有两种情况除外,一种情况是可以发送紧急数据,例如,允许用户终止在远端机上的运行进程。另一种情况是发送方可以发送一个1字节的数据报来通知接收方重新声明它希望接收的下一字节及发送方的滑动窗口大小。
窗口大小
接收方的窗口大小通常可以由接收进程控制,这将影响TCP的性能。插口API允许进程设置发送和接收缓存的大小,接收缓存的大小是该连接上所能够通告的最大窗口大小。默认的4096并不是最理想的窗口大小,而提高窗口的大小 有时 可以提高网络的吞吐量。
滑动窗口是用来加速数据传输。TCP要保证“可靠”,就需要对一个数据包进行ack确认表示接收端收到(窗口张开)。有了滑动窗口,接收端就可以等收到许多包后只发一个ack包,确认之前已经收到过的多个数据包。有了滑动窗口,发送端在发送完一个数据包后不用等待它的ack,在滑动窗口大小内可以继续发送其他数据包(窗口合拢)。
发送的数据TCP包都有一个序号。它是这么计算的:最初发送SYN时,有一个初始序号,根据RFC的定义,各个操作系统的实现都是与系统时间相关的。之后,序号的值会不断的增加,比如原来的序号是100,如果这个TCP包的数据有10个字节,那么下次的TCP包序号会变成110。
滑动窗口用于加速传输,比如发了一个seq=100的包,理应收到这个包的确认ack=101后再继续发下一个包,但有了滑动窗口,只要新包的seq与没有得到确认的最小seq之差小于滑动窗口大小,就可以继续发。
因为窗口的左边沿受另一端发送的确认序号的控制,因此不可能向左边沿移动。如果接收到一个指示窗口左边沿向左移动的ACK,则它被认为是一个重复的ACK,并被丢弃。
PUSH标志
发送方使用该标志通知接收方将所收到的数据全部提交给接收进程,这里的数据包括与PUSH一起传送的数据 以及 接收方TCP已经为接收进程收到的其他数据。
慢启动算法
当接收方和发送方之间存在多个路由器和速率较慢的链路时,一些中间路由器可能缓存分组,并可能耗尽存储器的空间,这严重影响了TCP的吞吐量。
TCP支持“慢启动”(slow strart),它为发送方的TCP增加了一个“拥塞窗口”(congestion window,cwnd)。
首先,拥塞窗口被初始化为1个报文段,每收到一个ACK就增加一个报文段。
理想的状态:
- 发送方开始发送一个报文,然后等待ACK。
- 当收到该ACK时,拥塞窗口从1增加到2,即可以发送2个报文段。
- 发送方再发送2个报文段,然后等待ACK,当收到这两个报文段的ACK时,拥塞窗口就增加为4。这是一种指数增加的关系。
注意,发送方取拥塞窗口和通告窗口中的最小值作为发送上限。
过程:
除了使用接收者窗口和拥塞窗口,TCP拥塞控制还使用第三个参数,阈值(threshold),初始化为64K。
- 当一个超时发生时,阈值降为当前拥塞窗口的一半,同时将拥塞窗口设为一个最大数据段长度。
- 然后使用慢启动算法来决定网络的容量,拥塞窗口增长到阈值时停止指数增长。
- 从这个点开始,每次成功的传输都会让拥塞窗口线性增长(每次只增长一个最大数据段长度)。
拥塞避免算法
慢启动算法用于保证新分组进入网络的速率与另一端返回确定的速率相等。
拥塞窗口是发送方使用的流量控制,通告窗口是接收方使用的流量控制。
例题:
例如,初始化时,阈值是8。即拥塞窗口最大为8。则先开始慢开始,按指数规律增长;当拥塞窗口增大从1到8,之后,已经到达了阈值,则就会执行拥塞避免加法增大。此时是成线性增长。当拥塞窗口达到12时,发生了超时。此时就会从新开始执行慢开始动作。即拥塞窗口从1开始,此时的阈值会降到超时时拥塞窗口的一半。即此时的新的阈值为6。即当新的慢动作开始,执行到拥塞窗口到6时,则会开始执行拥塞避免增大,即再次曾线性增长。
紧急方式
TCP提供了紧急方式,它使一端可以告诉另一端有些具有某些方式的"紧急数据"已经被放置在普通的数据流种。另一端被通知这个紧急数据已被放置在普通数据流中,由接收方决定如何处理。