tcp拥塞控制的现实问题
如果发送方发送数据太快,接收方可能来不及接收,就会造成数据丢失。所谓流量控制,就是让发送方的发送速率不要太快,让接收方能够及时收到。
利用滑动窗口机制,可以在TCP连接上轻松实现发送方的流量控制。
让A给B发送数据,当连接建立后,B告诉A:“我的接收窗口是rwnd = 400”(其中rwnd代表接收窗口)。因此,发送方的发送窗口不能超过接收方给定的接收窗口的值。请注意,TCP的窗口单位是字节,而不是消息段。图中没有显示TCP连接建立时的窗口协商过程。设每段长度为100字节,数据段的序号初始值设为1。大写ack表示报头中的确认位ack,小写ACK表示确认字段的值ACK。
从图中可以看出,B进行了三次流量控制。窗口第一次缩小到rwnd = 300,第二次缩小到rwnd = 100,最后缩小到rwnd = 0,即不允许发送方再发送任何数据。这种导致发送方暂停传输的状态将持续到主机B重新发出新的窗口值。B发送给A的所有三个数据段都设置为ACK = 1。只有当ACK=1时,确认号字段才有意义。
TCP对每个连接都有一个持续计时器。只要TCP连接的一端从另一端收到零窗口通知,它就会启动持续计时器。如果持续定时器设置的时间到期,将发送零窗口控制消息段(具有1字节的数据),并且接收该消息段的一方将重置持续定时器。
2.必须考虑传输速率。
可以使用不同的机制来控制发送TCP数据段的时间。比如:
Nagle算法:如果发送应用程序进程将待发送的数据逐字节发送到TCP发送缓冲区,发送方将首先发送第一个数据字节,并缓冲后面到达的所有数据字节。当发送方收到第一个数据字符的确认时,它将传输缓冲区中的所有数据组装成一个消息段,然后发送出去,同时继续缓存后面到达的数据。只有在收到前一段的确认后,才会发送下一段。当数据到达快,网速慢时,使用这种方法可以明显减少网络带宽。Nagle算法还规定,当到达的数据达到发送窗口大小的一半或消息段的最大长度时,将立即发送一个消息段。
另外,混淆窗口综合症:TCP接收方缓存已满,交互应用进程一次只从接收方缓存读取1字节(使得接收方缓存空间只释放1字节),然后向发送方发送确认,将窗口设置为1字节(但发送的数据报是40字节)。是的,发送方发送了1字节的数据(发送方的IP数据报是41字节)。接收方发送回一个确认,仍然将窗口设置为1字节。这样,网络的效率就很低了。为了解决这个问题,接收方可以等待一段时间,以便接收方缓冲区有足够的空间来容纳最长的消息段,或者接收方缓冲区有一半的空闲空间。只要这两种情况发生,接收方就会发回一条确认消息,告知发送方当前的窗口大小。此外,发送方不应该发送太小的数据段,而是将数据报累积到足够大的数据段中,或者达到接收方缓冲区空间大小的一半。
TCP的拥塞控制
1.拥塞:对资源的需求超过了可用资源。如果网络中很多资源同时短缺,网络的性能会明显恶化,整个网络的吞吐量会随着负载的增加而下降。
拥塞控制:防止过多的数据注入网络,使网络中的路由器或链路不会过载。拥塞控制要做的事情有一个前提:网络能够承受现有的网络负载。拥塞控制是一个全局过程,涉及所有主机、路由器和所有降低网络传输性能的相关因素。
流量控制:指点对点流量的控制,这是一个端到端的问题。流量控制要做的就是抑制发送方发送数据的速率,让接收方能够及时接收。
拥塞控制成本:需要获得网络内流量分布的信息。在实施拥塞控制之前,需要在节点之间交换信息和各种命令,以便选择控制策略和实施控制。这造成了额外的开销。拥塞控制还需要分配一些资源给每个用户单独使用,使得网络资源无法得到更好的享用。
2.几种拥塞控制方法
慢启动、拥塞避免、快速重传和快速恢复。
2.1慢启动和拥塞避免
发送方维护拥塞窗口(CWND)的状态变量。拥塞窗口的大小取决于网络的拥塞程度,并且是动态变化的。发送者使他的发送窗口等于拥塞。
发送方控制拥塞窗口的原则是,只要网络不拥塞,拥塞窗口就会增大,以发送更多的数据包。但只要网络拥塞,拥塞窗口就会缩小,以减少注入网络的数据包数量。
慢启动算法:当主机开始发送数据时,如果立即向网络注入大量数据字节,可能会造成网络拥塞,因为现在网络负载不明确。所以比较好的方法是先检测,也就是把传输窗口从小到大逐渐增大,也就是把拥塞窗口值从小到大逐渐增大。通常,在开始发送消息段时,拥塞窗口cwnd被设置为最大消息段MSS的值。然而,在接收到新消息段的每个确认之后,拥塞窗口最多增加一个MSS值。通过以这种方式逐渐增加发送方的拥塞窗口cwnd,可以使分组注入网络的速率更加合理。
拥塞窗口cwnd在每一轮传输中都加倍。一轮传输的时间实际上是往返时间RTT。但是“传输回合”更强调连续发送拥塞窗口cwnd允许的所有段,并接收已发送的最后一个字节的确认。
另外,“慢启动”并不是说cwnd的增长速度慢,而是在TCP开始发送一个报文段的时候设置cwnd=1,让发送方在开始的时候可以只发送一个报文段(为了测试网络拥塞),然后逐渐增加cwnd。
为了防止拥塞窗口cwnd增长过快导致网络拥塞,还需要设置一个慢启动阈值ssthresh状态变量(如何设置ssthresh)。慢启动阈值ssthresh可以如下使用:
当cwnd
当cwnd > Ssthresh时,停止使用慢启动算法,切换到拥塞避免算法。
当cwnd = ssthresh时,慢启动算法和拥塞控制避免算法都可以使用。
拥塞避免算法:使拥塞窗口cwnd缓慢增加,即每往返一次RTT,发送方的拥塞窗口cwnd加1,而不是加倍。这样拥塞窗口cwnd按照线性规律缓慢增长,比慢启动算法慢很多。
无论在慢启动阶段还是拥塞避免阶段,只要发送方判断网络拥塞(基于未收到确认),就需要将慢启动阈值ssthresh设置为发生拥塞时发送方窗口值的一半(但不小于2)。然后将拥塞窗口cwnd重置为1,并实施慢启动算法。这样做的目的是快速减少主机发送到网络的数据包数量,让拥塞的路由器有足够的时间处理队列中积压的数据包。
如下图所示,上面的拥塞控制过程用具体的数值来说明。现在发送窗口和拥塞窗口一样大。
& lt1 & gt;当TCP连接初始化时,将拥塞窗口cwnd设置为1。如前所述,为了便于理解,图中的窗口单元使用的是段数而不是字节数。慢启动阈值的初始值设置为16段,即cwnd = 16。
& lt2 & gt当执行慢启动算法时,拥塞窗口cwnd的初始值是1。以后,发送方每收到一个新消息段的确认ack,就将拥塞窗口值改为1,然后开始下一轮传输(图中横坐标为传输轮次)。因此,拥塞窗口cwnd随着传输轮次呈指数增长。当拥塞窗口cwnd增大到慢启动阈值ssthresh(即cwnd=16)时,改为执行拥塞控制算法,拥塞窗口线性增长。
& lt3 & gt假设当拥塞窗口的值增加到24时,网络将超时(这很可能是网络的拥塞)。更新后的ssthresh值变为12(即超时时变为拥塞窗口值24的一半),拥塞窗口重置为1,执行慢启动算法。当cwnd=ssthresh=12时,改为执行拥塞避免算法,拥塞窗口线性增长,MSS的大小随着每次往返时间而增加。
强调:“拥堵避免”并不意味着可以完全避免拥堵。使用上述措施仍然无法完全避免网络拥塞。“拥塞避免”是指在拥塞避免阶段控制拥塞窗口线性增长,使网络不容易拥塞。