深刻理解TCP(二)

   上一篇http://www.cnblogs.com/whc-uestc/p/4715334.html中已经讲到TCP跟踪一个拥塞窗口来(cwnd)提供拥塞控制服务,经过调节cwnd值以控制发送速率。那么TCP如何基于丢包事件来设置cwnd值?经过TCP拥塞控制算法来实现。TCP拥塞控制算法主要有三部分:慢启动、拥塞避免、快速恢复。html

一、慢启动算法

   当一条TCP链接开始时,cwnd的值通常初始设置为MSS的较小值。由于只有当发送方接收到ACK,才会更新cwnd的值,因此在一个RTT时间内,发送方只能发送cwnd字节大小的数据,这就使得初始发送速率大约为MSS/RTT。这是一个较小的值,大部分的带宽仍是空闲的,如何迅速更新cwnd以提升带宽利用率??网络

  慢启动状态:cwnd的值以1个MSS开始而且每当传输的报文段首次被确认就增长一个MSS。spa

  • 刚开始在第一个RTT中,cwnd只有1个MSS,发送一个报文;
  • 收到一个ACK,此时cwnd增长1个MSS,在第2个RTT,cwnd为2个MSS,发送两个报文;
  • 会收到两个ACK,此时cwnd增长2个MSS,因此在第3个RTT中,cwnd为4个MSS,发送4个报文;
  • 依次类推。

  从上面的过程,不难发现每过一个RTT,发送速率就会翻一倍。虽然起始速率只有MSS/RTT,可是在慢启动的过程当中是以指数增加的。固然,带宽是有限的,发送速率不可能无限制地增加,那么问题来了,何时结束这种指数增加??htm

  (1) 当有一个超时引发的丢包事件(拥塞)时,TCP发送方将cwnd设置为1并从新开始慢启动过程;同时将慢启动阈值ssthresh设置为cwnd/2。blog

  (2) 在(1)从新慢启动过程当中,当cwnd的值增加到大于等于慢启动阈值ssthresh时,慢启动结束,同时转移到拥塞避免模式排序

    (3) 若是在慢启动的过程当中,发送方收到3个冗余的ACK,TCP就结束慢启动过程,执行快速重传并进入快速恢复模式事件

二、拥塞避免get

   上面说到,只有当再次启动慢启动而且cwnd增加到大于等于慢启动阈值ssthresh时,才会进入拥塞避免模式,因此当进入到拥塞避免时,cwnd的值大概是在第一次遇到拥塞时的cwnd的值的一半。此时若是继续进行慢启动就会使cwnd的值翻倍从而可能致使拥塞。因此拥塞避免模式对于每次收到的ACK,并不像慢启动那样直接将cwnd增长一个MSS字节,而是增长MSS*MSS/cwnd字节。也就是说当MSS=1460字节,cwnd为14600字节,那么每次收到一个ACK,cwnd增长1460*1/10字节,只有收到10个ACK,cwnd才会增长一个MSS。总结

  问题来了,与慢启动同样,难道cwnd的值也是这么一直增加下去么??何时结束呢?

  (1) 当有一个超时引发的丢包事件(拥塞)时,同慢启动同样,TCP发送方将cwnd设置为1并从新开始慢启动过程;同时将ssthresh设置为cwnd/2。

    (2) 当收到3个冗余的ACK时,ssthresh设置为cwnd/2,TCP将cwnd的值设置为ssthresh+3进入快速恢复模式

三、快速恢复

  对于引发TCP进入快速恢复状态的缺失报文段,对收到的每一个冗余ACK,cwnd的值增长1个MSS,当收到新的ACK时TCP把cwnd设置为ssthresh的值进入拥塞避免状态

  当在快速恢复阶段出现超时事件,cwnd的值被设置为1个MSS,而且ssthresh的值设置为cwnd的一半,进入慢启动状态

  TCP的拥塞控制实际上是加性增、乘性减(AIMD)的拥塞控制方式,当TCP链接的路径上没有拥塞(经过判断丢包事件)时,发送速率加性增;当出现丢包事件时,发送速率乘性递减。咱们知道UDP自己是没有实现拥塞控制的,其实若是大量使用UDP而没有任何约束,那么网络就很容易出现死锁,使得端到端之间不多有数据可以被传输。

四、总结:

  固然,虽然UDP是不可靠、无链接的传输层协议,而TCP是面向链接的提供可靠数据传输的传输层协议。可是UDP的应用依旧很广,像DNS,QQ都是用的是UDP,不少人会奇怪,为何TCP提供了那么多服务,为何不用TCP而用这么不可靠的UDP呢??

  其实不管TCP仍是UDP,在如此复杂的网络中,并不多是彻底可靠的。

  • TCP只是经过确认和重传机制来保证它的可靠性,而UDP并无确认和重传机制。
  • TCP提供有序的数据流服务,UDP每一个数据包是单独的,在接收方并不保证提交给应用层的数据包是有序的。
  • TCP提供流量控制和拥塞控制,经过流量控制,可让发送方和接收方的应用层从接收缓冲区读取数据的速率匹配,从而不会由于接收缓冲区满而发生丢包;经过拥塞控制,每个经过拥塞链路的TCP链接都可以平等地共享链路带宽。

  可是正由于TCP提供了这么多的服务,使得TCP变得很臃肿,很难发送大容量的数据;这时候,轻量的传输层协议UDP就站出来了。UDP很简单,不提供那么多的机制和服务,使得UDP的传输速率能够比TCP快不少。固然有人会说,UDP丢包率很高,UDP接收到无序的数据包,UDP没有拥塞,可能致使网络瘫痪等等一些问题。

  由于传输层及以上的层次都是只在端系统中实现的,在网络分组交换机中只有网络层一下的实现,也就是说TCP的全部这些服务都是基于端到端的服务。既然是端到端的服务,那么上述的全部问题均可以经过上层(也就是应用层)来实现,经过在应用层把发送的数据进行编号,就能够在接收端对接收的数据进行排序,从而的到有序的数据;经过在应用层添加确认和重传,就能够大大下降丢包率;经过在应用层加一个窗口,来达到流量控制和拥塞控制的目的。固然具体基于UDP的实现其实并不须要把因此TCP的服务都在应用层实现,不然还不如用TCP。咱们只须要实现那些咱们须要和关系的服务便可,好比说咱们须要下降丢包率,咱们就只实现重传机制。(固然咱们也能够彻底不用传输层,应用层直接经过网络层通讯)

  UDP很自由,能够任由上层来实现;TCP很全面,能够给上层提升可靠的数据传输和各类机制。到底选择哪种传输层协议,其实还要根据具体的应用来选择。存在既有价值,关键是各方面的权衡而已。

版权全部,欢迎转载,转载请注明出处。

相关文章
相关标签/搜索