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