当前的 TCP 实现将 TCP 端节点之间的中间网络视为一个不透明的“黑盒”。 TCP 包进入和流出这个盒子。有些时候进入盒子的包被丢失了。因为今天的数字和光媒体上出现比特级错误的机会非常少, TCP 的设计者们就假设包的丢失很大程度上是因为路由器的拥塞,也即是路由器用来容纳进入包的缓冲已经被填满了,这样路由器会静默地丢弃接下来进入的包。
   
    尽管 TCP 可以检测到 TCP 包的丢失并且进行重传,但是从 TCP 处理过程,重传过程和吞吐率下降这些方面看,这个重传过程将会耗费很大。

 

  当一个发送的 TCP 端节点检测倒一个包丢失时,可以进行快速重传或者包的重传计时器超时而重传。然后该 TCP 端节点减小发送窗口 ( 在等待响应之前可以发送的包数量 ) ,进行慢启动和拥塞避免算法 (RFC 2001) 。这会立刻降低发送端的发送速率,以便路由器来减轻拥塞。发送端会逐渐将发送窗口恢复倒拥塞发生前的大小。

 

  尽管因为路由器拥塞而产生的包丢失是偶然发生的事件,它们并不会负面地影响块数据传输,只是会增加一些重传数据包和恢复发送速率的时间。慢启动和拥塞避免算法对于时间敏感的,成块数据流的控制效果非常好。然而, TCP 处理丢包的方法对于交互式的,丢失敏感和时间敏感的流量来说效果不是很好。

 

  另外一个关于路由器拥塞的问题是拥塞对于多个数据流的影响。当路由器开始丢弃进入的数据包时,它一般并不区分数据流的不同。当多个 TCP 数据流都产生包丢失时,所有的数据流都要减少自身的发送速率。根据路由器拥塞减轻的程度,多个 TCP 数据流将会逐渐恢复自身的发送速率。这会降低路由器及相关链路的使用率,直到所有的 TCP 数据流恢复到以拥塞之前的速率进行发送。路由器从拥塞状态又进入到了低使用状态。

 

  这种拥塞后因为重传和低链路使用而带来的吞吐量问题,是仅仅通过发送端来管理拥塞的结果。为了避免因为路由器拥塞而带来的丢包而产生的一系列问题, TCP/IP 的设计者们创建了一些用于主机和路由器的标准。这些标准描述了在 IP 路由器上进行的主动队列管理算法 (AQM)(RFC 2309) ,使得路由器能够监控转发队列的状态,以提供一个路由器向发送端报告发生拥塞的机制,让发送端在路由器开始丢包前降低发送速率。这种路由器报告和主机响应机制被称为显式拥塞通告 (ECN)(RFC 3168)

 

  当拥塞发生时,发送主机必须仍然在降低它们的发送速率。然而,通过避免包的丢失,发送主机无需进入重传过程,丢失敏感的数据包流也不会因为拥塞而受到很大影响。

 

  显式拥塞通告

 

   IP TCP 使用包头中的未使用字段来支持 ECN

 

  在网络层 (IP) ,一个发送主机必须能够表明自身可以进行 ECN ,路由器在转发时必须能够表明它正在经历拥塞。

 

  在传输层 (TCP) TCP 端必须对对方表明自身是可以进行 ECN 操作的。接收端必须能够通知发送端它收到了一个来自路由器的拥塞通告。发送端必须能够通知接收端它受到了来自接收端的通告并且已经降低了发送速率。
    
    IP 包头中的 8 位的服务类型域 (TOS) 原先在 RFC791 中被定义为表明包的发送优先级,时延,吞吐量,可靠性和消耗等特征。在 RFC2474 中被重新定义为包含一个 6 位的区分服务码点 (DSCP) 和两个未用的位。 DSCP 值表明一个在路由器上配置的和队列相关联的发送优先级。 IP ECN 的支持使用到了 TOS 域中剩下的这两位。如图 1 所示。

 

  在 RFC2474 TOS 域未使用的两位在 RFC3168 中被定义为 ECN 域,包含如下值:

 

   00 :发送主机不支持 ECN
   01 或者 10 :发送主机支持 ECN
   11 :路由器正在经历拥塞
一个支持 ECN 的主机发送数据包时将 ECN 设置为 01 或者 10 。对于支持 ECN 的主机发送的包,如果路径上的路由器支持 ECN 并且经历拥塞,它将 ECN 域设置为 11 。如果该数值已经被设置为 11 ,那么下游路径上的路由器不会修改该值。

 

TCP ECN的支持
  当一个 IP包的 ECN域被路由器设置为 11时,接收端而非发送端被通知路径上发生了拥塞。 ECN使用 TCP头部来告知发送端网络正在经历拥塞,并且告知接收端发送段已经受到了接收端发来的拥塞通告,已经降低了发送速率。
    
    TCP
ECN的支持使用 TCP中预先定义的保留位。 ECN定义两个新的标志,如图 2所示:
   ECEECN响应标志被用来在 TCP3次握手时表明一个 TCP端是具备 ECN功能的,并且表明接收到的 TCP包的 IP头部的 ECN被设置为 11。更多信息请参考 RFC793
   CWR:拥塞窗口减少标志被发送主机设置,用来表明它接收到了设置 ECE标志的 TCP包。拥塞窗口是被 TCP维护的一个内部变量,用来管理发送窗口大小。
  当两个支持 ECNTCP端进行 TCP连接时,它们 交换SYNSYN-ACKACK包。对于支持 ECNTCP端来说, SYN包的 ECECWR标志都被设置了。 SYN-ACK只设置 ECE标志。
  一个支持 ECNTCP主机在支持 ECNTCP连接上发送设置了 IP头部为 10或者 01TCP包。支持 ECN的路由器在经历拥塞时设置 IP头部的 ECN域为 11。当一个 TCP接收端发送针对收到的一个设置 ECN位为 11TCP包的响应时,它设置 TCP包头中的 ECE,并且在接下来的 ACK中也做同样设置。
  当发送主机接收到设置了 ECE标志的 ACK时,它就像感知到包丢失一样,开始减少发送窗口,运行慢启动过程和拥塞避免算法。在下一个数据包中,发送者设置 CWR标志。在接收到新的设置 CWR标志的包时,接受者停止在接下来的 ACK中设置 ECE标志。
    
   
3展示了一个在支持 ECNTCP端节点之间的一个 TCP连接的例子,它们之间的一个支持 ECN的路由器正在经历拥塞。
  在这个例子中, TCPA发送数据给 TCPBTCPA一次性发送 5个包。包 2通过一个拥塞的支持 ECN的路由器转发,将 IP包头的 ECN位设置为 11。当 TCPB接收到这个包,它发送设置了 ECE标志的 ACK。当 TCPA接收到第一个设置了 ECEACK以后,它降低发送速率,并且在发送下一个包 (6)时设置其 CWR标志。通过接收包 6TCP端将不对接下来的 ACK包设置 ECE标志。详情请参考 RFC 3168
  
windows对ECN的支持
   Vista支持 ECN但是缺省是关闭的。你可以通过 netsh interface tcp set global ecncapability=enabled来打开支持。因为 ECN使用到了 IPTCP包头中以前未使用或者保留的位,中间的 网络设备如路由器和 防火墙将会静默地丢弃 ECN域设置为非 0值的包。为了防止出现这种情况,请对你的 网络设备进行适当的配置和升级以支持 ECN