我们看到TFTP使用了停止等待协议。数据发送方再发送下一个数据块之前需要等待接收对已发送数据的确认。TCP所使用的被称为滑动窗口协议的另一种形式的流量控制方法。该协议允许发送方再停止并等待确认前可以连续发送多个分组(但发送分组的总大小不能超过通告窗口)。由于发送方不必每发送一个分组就停下来等待确认,因此该协议可以加速数据的传输。
正常数据流
通常使用的“隔一个报文段确认”的策略(即每收到两个报文段发送一次确认,不是一定都是这样)。
当发送方发送一段数据后,接受发发送ACK,但通告其窗口大小为0,这说明接收方已收到所有数据,但这些数据都在接收方的TCP缓冲区,因为应用程序还没有机会读取这些数据。这时候发送发就会停止后续数据发送,等待接收方发送一个窗口更新。当接收方处理TCP缓冲区里的数据后,有闲置的空间时就会发送一个ACK(许多TCP实现在窗口大小增加了两个最大报文段长度或者最大可用窗口的50%时发送这个窗口更新,不会因为应用程序读取了10个字节,就通告窗口大小为10个字节),并通告窗口大小为缓冲区的大小。
滑动窗口
在这个图中,我们将字节从1至11进行标号。接收方通告的窗口称为提供的窗口,它覆盖了从第4字节到第9字节的区域,表明接收方已经确认了包括第3字节在内的数据,且通告窗口大小为6。我们知道窗口大小是与确认序号相对应的。发送方计算它的可用窗口,该窗口表明多少数据可以立即被发送。当接收方确认数据后,这个滑动窗口不时地向右移动。窗口两个边沿的相对运动增加或减少了窗口的大小。
称窗口左边沿向右边沿靠近为窗口合拢。这种象限发生在数据被发送和确认时。
当窗口右边沿向右移动时将允许发送更多的数据,我们称之为窗口张开。这种现象发生在另一端的接收进程读取已经确认的数据并释放了TCP的接收缓存时。
当右边沿向左移动时,我们称之为窗口收缩。RFC强烈建议不要使用这种方式。
慢启动
发送方一开始便向网络发送多个报文段,直至达到接收方通告的窗口大小为主。当发送方和接收方处于同一个局域网时,这种方式是可以的。但是如果在发送方和接收方之间存在多个路由器和速率较慢的链路时,就有可能出现一些问题。一些中间路由器必须缓存分组并有可能耗尽存储器的空间。
TCP需要支持一种被称为“慢启动”的算法(不允许开始一下子就发送通告窗口的大小,需要缓慢增加速率)。该算法通过观察到新分组进入网络的速率应该与另一端返回确认的速率相同而进行工作。
慢启动为发送方的TCP增加了另一个窗口:拥塞窗口
拥塞窗口
拥塞窗口(congestion window),记为cwnd。当与另一个网络的主机建立TCP连接时,拥塞窗口被初始化为1个报文段(1个报文段即为一个MSS,MSS=MTU-40)。每收到一个ACK,拥塞窗口就增加一个报文段(cwnd以字节为单位,但是慢启动以报文段大小为单位进行增加)。发送方取拥塞窗口与通告窗口中的最小值作为发送上限。拥塞窗口发送发使用的流量控制,而通告窗口则是接收方使用的流量控制。
发送方开始时发送一个报文段,然后等待ACK。当收到该ACK时,拥塞窗口从1增加为2,即可以发送两个报文段。当收到这两个报文段的ACK时,拥塞窗口增加为4.(当然这是一种理想的增长,因为发送两个报文段,接收方不一定会发回2个ACK,一般只会发送会一个ACK来确认这两个包已经收到,有时候哪怕拥塞窗口为4了,也不一定下一次就会发送4个报文段,也可以只发送3个。)这是一种指数增加的关系。
在某些点上可能到达了互联网的容量,于是中间路由器开始丢弃分组。这就通知发送方它的拥塞窗口开得过大。
发送一个分组的时间
通常发送一个分组的时间取决于两个因素:传播延时(在网线里面传播的延时)和发送延时(10M以太网和10G以太网)。对于一个给定的两个节点之间的通路,传播时延一般都是固定的,而发送时延则取决于分组的大小。在速率较慢的情况下发送时延起主要作用,而在千兆比特速率下传播时延则占主要地位