《计算机网络自顶向下方法》学习笔记02:运输层。
运输层介于应用层与网络层之间,为应用层提供了直接的通信服务。在应用层时已经介绍了两种运输层协议UDP和TCP,本章主要介绍这两个协议和运输层的原理及实现。
第三章 运输层
1.概述和运输层服务
运输层协议为运行在不同主机上的应用进程之间提供了逻辑通信功能。运输层协议是在端系统实现的,将应用程序的报文转换为较小的块,加上运输层首部生成运输层分组,称为报文段,将报文段交给网络层,由网络层发送到目的地。
因特网提供了两种可用的运输层协议:UDP(用户数据报协议),TCP(传输控制协议)。UDP提供不可靠服务,而TCP提供面向连接的可靠数据传输,还提供拥塞控制。网络层的协议即网际协议IP,提供的是不可靠服务,不确保报文段的交付和按序交付,因此本章主要讨论的一个问题是TCP如何提供可靠数据传输,另一个主要讨论的问题是TCP如何实现拥塞控制。
2.多路复用与多路分解
运输层从紧邻其下的网络层接收报文段。运输层负责将报文段进程交付给主机上运行的适当进程。一个进程有一个或多个套接字,运输层实际上是将数据交给中间的套接字。接收主机可能同时有多个套接字,因此每个套接字都有一个唯一的标识符。为了将运输层报文段定向到合适的套接字,运输层报文段有一些字段,包含了套接字的标识符。通过这些字段,将运输层报文段中的数据交付到正确的套接字的工作称为多路分解。从不同套接字中收集数据块,将数据块封装并添加首部信息产生报文段,发送到网络层的过程工作称为多路复用。
每个套接字都有唯一的标识符,每个报文段都有特殊字段来指示该报文要交付到的套接字。套接字需要使用端口号进行标识。端口号是一个16bit的数,其中0-1023为熟知端口号。保留给HTTP,FTP等熟知的应用层协议。
一个UDP套接字是一个二元组标识的,包含一个目的IP地址(标识主机)和一个目的端口号(标识具体的套接字)。接收主机的运输层收到报文段后,通过首部中的目的端口号,将报文段定向到相应的套接字。
一个TCP套接字是由一个四元组(源IP地址,源端口号,目的IP地址,目的端口号)标识的。这四个值标识了一个连接,接收主机通过四个值将报文段定向到对应套接字。由于TCP是面向连接的,不同的源IP地址和源端口号与同一个目的IP的同个目的端口号建立的是不同的连接,使用的也是不同的套接字。但是初始创建连接时,连接还没有建立,因此使用的是同一个套接字(欢迎套接字)。连接建立后,接收端进程将创建一个新的套接字供该连接使用。
3.无连接运输:UDP
UDP是无连接的运输,只在IP的基础上进行复用和分解,并增加了少量的差错检测。UDP不能提供可靠的传输服务,但有以下优点:
- 控制更加精细。采用UDP时,UDP会将数据打包直接传递给网络层,不像TCP存在拥塞控制机制,发送可能受到遏制。
- 无需建立连接。UDP不会引入建立连接的时延。因此DNS就是运行在UDP之上的。
- 无连接状态。UDP不维护连接状态。而TCP则需要维护包括接收和发送缓存,拥塞控制参数和确认号等连接状态。
- 分组首部开销小。仅有8字节。
除了不能提供可靠传输,UDP还可能导致其他问题,因为缺乏拥塞控制,UDP可能导致发送方接收方之间的高丢包率,挤垮TCP会话。
UDP报文段由源端口号,目的端口号,长度和校验和组成,共8个字节。其中的校验和提供了差错检测功能,因为链路层协议可能没有提供差错检测,而报文段的传输可能经过一条没有使用差错检测协议的链路。因此UDP在端到端基础上,在运输层提供差错检测,这称为端到端原则。
*4.可靠数据传输原理
可靠传输问题不仅在运输层出现,也在链路层及应用层出现。实现可靠传输服务是可靠数据传输协议的任务。一般情况下,都是在下层协议提供不可靠数据传输(udt)下,建立可靠数据传输协议。由于可靠数据传输(rdt)不仅适用于运输层,收发端交换的数据以下称为分组,而不是运输层的报文段。
4.1 构造可靠数据传输协议
经完全可靠信道的可靠数据传输 rdt1.0
经完全可靠信道的可靠数据传输,接收与发送方不需要进行任何通信。发送方只需接收高层的数据,产生分组并发送到信道中,而接收方只需要从信道接收分组,从分组中取出数据交给上层。
经具有比特差错信道的可靠数据传输 rdt2.0
实际情况下,底层信道的模型是会出现比特差错的模型,在分组的传输,传播或缓存的过程中都可能出现比特差错。为了处理差错,接收方需要对接收到的分组进行确认,发出肯定确认告知发送方分组被接收,发出否定确认告知发送方重发分组。基于这种重传机制的可靠数据传输协议称为自动重传协议(ARQ)。ARQ协议需要三种功能处理比特差错的情况:
- 差错检测:通过检验和字段,使接收方能够检测到比特差错。
- 接收方反馈:接收方需要进行肯定确认(ACK),否定确认(NAK),只需要一个bit的分组就可以进行确认。
- 重传:接收方接收到有差错的分组时,发送方重传分组。
采用以上这种重传机制,发送方在发送分组后,将等待接收方的确认分组,决定是否重传还是传输新的分组。由于这种行为,rdt2.0这样的协议被称为停等协议。
由于信道本身可能出现差错,因此必须考虑确认分组ACK或NAK出现差错的情况。在这种情况下,发送方不知道接收方是否正确收到了分组。解决该问题的方式是,如果发送分组不能确定接收方是否接收到了正确的分组,就重新发送分组。这种方式给信道引入了冗余分组。但是接收方还需要知道接收到的是新的分组还是重传的分组,因此对于分组需要进行一个序号,需要只需要为0或1,让接收方能够区别分组是否和上一个接收到的分组一样就可以。
经具有比特差错的丢包信道的可靠数据传输 rdt3.0
除了比特差错,丢包也是常见的一种情况。解决丢包的方式和处理比特差错一样,如果没有接收到确认分组(发送的分组丢失或确认的ACK丢失,又或者只是分组或ACK延时),就重传数据分组。新的问题是,到底等待多久才能判断分组丢失。这个时间至少大于一个往返时延,要根据情况设置。为了实现以上这种基于时间的重传机制,还需要一个倒计数定时器,发送方每发送一个分组就启动一个定时器,定时器超时就进行重传。解决冗余分组的方式则和rdt2.0相同。因为分组序号在0和1之间交替,rdt3.0也被称为是比特交替协议。
4.2 流水线可靠数据传输协议
以上所形成的以停等协议为核心的可靠数据传输协议是功能正确的,但是在性能方面存在大的问题,因为发送方的信道利用率太低了,大量时间都在等待确认分组。而确认分组至少需要一个往返时延RTT才能回到发送方,还要加上协议处理时间和中间路由器的时延。这个性能问题的解决办法就是不以停等方式运行,允许发送方发送多个分组。例如发送方可以发送三个分组后再等待确认,这样的方式被称为流水线。不过,在提升性能的同时,采用流水线也会带来新的问题。
- 必须增加序号范围,因为输送中的分组有多个。
- 发送方和接收方需要缓存多个分组。
- 需要处理丢失,损坏及延时过大的分组。两种基本方法是:回退N步;选择重传。
4.3 回退N步(GBN)
在回退N步协议GBN中,允许发送方发送多个分组,不需等待确认,但是未确认的分组数不能超过某个最大允许数N。定义基序号base为最早未确认分组的序号,下一个序号nextseqnum为下一个待发分组的序号,则:
|base |nextseqnum
---------------------------------------------------------------------
已发送且确认的 | 已发送未确认 |未发送的 |
----------------------------------------
窗口长度 N
GBN协议也常被称为滑动窗口协议。分组的序号在分组首部的字段(k位),范围为0-2^k-1。GBN发送方响应三种事件:
- 上层调用:窗口未满,则发送分组,否则告知上层。上层可能过一会儿再试,也可能发送方直接把上层数据缓存。
- 接收ACK:GBN协议中,对分组的确认方式为累积确认。接收到n的ACK,则序号小于等于n的分组都被确认接收。
- 超时:如果出现超时,重传所有已发送但未被确认过的分组。GBN协议中只有一个定时器,最早发送且未被确认的分组启动计时器,接收到确认分组则重启计时器。
GBN协议中,接收方会丢弃所有失序的分组,因为发送方会重传这些分组。直接丢弃这些分组,接收缓存简单,不需要缓存失序分组,接收方唯一需要维护的信息就是下一个按序接收的分组的序号。
4.4 选择重传(SR)
如果采用GBN协议,一旦最早发送的未确认分组超时,就需要从该分组开始重传,且接收方接收到的不按序的分组都会被丢掉。在信道差错率增加,时延很大的情况下,GBN可能大量重传分组。选择重传协议SR改进了这一点,只让发送方重传可能出错的分组。接收方将缓存失序的分组,并逐个对分组进行确认,连续的几个分组都收到后一起交付给上层。而发送方的每一个分组都有自己的定时器,超时后只重传一个分组,如果收到了最小未收到确认的分组的对应ACK,就将窗口重新移动到具有最小序号的未确认分组处。
对于已收到的那些分组,接收方会重新进行确认,这是有必要的,否则发送方可能停留在一个固定的窗口(因为不进行累积确认了,不重新确认窗口就不移动了)。
另外,考虑到序号是有限的,发送方与接收方窗口的不同步会导致严重的问题。例如,假设序号只有0,1,2,一种情况是正常的按照0,1,2,0来发送分组,另一种情况是分组0的ACK丢失了,发送次序是0,1,2,0(重传0),因为有这两种不同的情况,接收方无法确认接收到的分组是重复发送的还是新的分组。因此必须限制窗口的大小,避免这种情况的发生。窗口长度必须小于或等于序号空间大小的一半。这样假设发送方没有收到正确的ACK,窗口不移动,接收方接收到了分组,一直向后移动,最后的结果就是发送方的窗口占了一半序号,接收方的窗口占了一半的序号,接收方的窗口最大值刚好停在发送方的窗口最小值前面,而不会发生序号重复。
*5.面向连接的运输:TCP
5.1 TCP连接
TCP连接是面向连接的,这种连接是一种逻辑上的连接,因为TCP协议只在端系统运行。TCP连接是全双工的连接,也是点对点的连接。两个不同主机的进程通过三次握手来建立连接,并通过连接发送数据。
TCP连接建立后,应用进程就可以互相发送数据了。客户进程通过套接字将数据交给TCP,TCP将数据存储到连接的发送缓存中,接下来TCP会从发送缓存中取出数据交给网络层。TCP可取出并添加到报文段的数据大小受限于最大报文长度MSS,而MSS又通常根据最大链路层帧长度(最大传输单元MTU)来设置,MSS要保证一个报文段加上TCP/IP首部长度(40字节)适合链路层帧。以太网和PPP链路层协议都有1500字节的MTU,因此MSS的典型值为1460字节。TCP接收端接收到报文段,将数据放到接收缓存中,应用程序从该缓存中读取数据。
根据以上的讨论,TCP连接的组成包括:一台主机上的缓存,变量和与进程连接的套接字,另一台主机上的缓存,变量和与进程连接的套接字。
5.2 TCP报文
TCP报文的结构如下:
- 源端口:16bit,写入源端口号,用来标识发送该TCP报文段的应用进程。
- 目的端口:16bit,写入目的端口号,用来标识接收该TCP报文段的应用进程。
- 序号:32bit,指出本TCP报文段数据载荷的第一个字节的序号。
- 确认号:32bit,指出期望收到对方下一个TCP报文段的数据载荷的第一个字节的序号,同时也是对之前收到的所有数据的确认。
- 确认标志位ACK:取值为1时确认号字段才有效,取值为0时确认号字段无效。TCP规定,连接建立后所有传送的TCP报文ACK均置1。
- 数据偏移:4bit,以4字节为单位。用来指出TCP报文段的数据载荷部分的起始处距离TCP报文段的起始处有多远。这个字段实际上是指出了TCP报文段的首部长度。取值为20-60。
- 保留:6bit,保留,目前置为0。
- 窗口:16bit,字节为单位,指出发送本报文段的一方的接收窗口。
- 校验和:16bit,检查范围包括TCP报文段的首部和数据载荷两部分。在计算校验和时,要在TCP报文段的前面加上12字节的伪首部。
- 同步标志位SYN:在TCP连接建立时用来同步序号。
- 终止标志位FIN:用来释放TCP连接。
- 复位标志位RST:用来复位TCP连接。当RST=1时,表明TCP连接出现了异常,必须释放连接,然后再重新建立连接。RST置1还用来拒绝一个非法的报文段或拒绝打开一个TCP连接。
- 推送标志位PSH:接收方的TCP收到该标志位为1的报文段会尽快上交应用进程,而不必等到接受缓存都填满后再向上交付。
- 紧急标志位URG:取值为1时紧急指针字段有效。取值为0时紧急指针字段无效。
- 紧急指针:占16bit,以字节为单位,用来指明紧急数据的长度。
当发送方有紧急数据时,可将紧急数据插队到发送缓存的最前面,并立即封装到一个TCP报文段中进行发送。紧急指针会指出本报文段数据再和部分包含了多长的紧急数据,紧急数据之后是普通数据。
- 扩展首部
- 最大报文段长度MSS选项:TCP报文段数据载荷部分的最大长度。
- 窗口扩大选项:为了扩大窗口(提高吞吐率)。
- 时间戳选项:用来计算往返时间RTT;处理序号超范围的情况,又称为防止序号绕回PAWS。
- 选择确认选项
- 填充:保证报文段首部能被4整除
5.3 往返时间的估计与超时
TCP与rdt一样,采用超时重传机制来处理报文段的丢失问题。对于超时重传机制,一个重要的问题就是超时时间的设置,该时间必须大于往返时间RTT,因此需要估计RTT,并根据RTT设置时间间隔。
TCP连接的往返时间通过某个时刻测量的SAMPLERTT进行估计,且为了得到一个典型的RTT,要对SAMPLERTT取均值,还要反映RTT的波动。因此SAMPLERTT均值如下:
E s i t i m a t e d R T T = ( 1 − α ) R T T + α R T T EsitimatedRTT=(1-α)RTT+αRTT EsitimatedRTT=(1−α)RTT+αRTT
按照RFC文档,α取1/8。除了RTT均值外,RTT偏差也有计算意义,定义如下:
D e v R T T = ( 1 − β ) D e v R T T + β ∣ S a m p l e R T T − E s t i m a t e d R T T ∣ DevRTT=(1-β)DevRTT+β|SampleRTT-EstimatedRTT| DevRTT=(1−β)DevRTT+β∣SampleRTT−EstimatedRTT∣
β推荐值为0.25。根据以上的平均RTT和RTT偏差,超时间隔定义如下:
T i m e o u t I n t e r v a l = E s t i m a t e d R T T + 4 D e v R T T TimeoutInterval=EstimatedRTT+4DevRTT TimeoutInterval=EstimatedRTT+4DevRTT
使用上式计算,当波动较小时,间隔就小一些,波动较大,间隔大一些。初始的TimeoutInterval推荐为1s。出现超时后,该值加倍,以免后继报文段过早出现超时。只要收到报文段并更新EstimatedRTT,就更新该值。
5.4 可靠数据传输
TCP在IP的不可靠的尽力而为服务上创建了可靠数据传输服务,基于可靠传输的基本原理。由于定时器的管理需要相当大的开销,因此TCP使用单一的定时器。TCP发送方只处理三类时间:从上层程序接收数据;定时器超时;收到ACK;。简化的描述如下:
loop{
switch(event)
event1:
接收上层应用的数据e,生成具有nextseqnum的TCP报文段
if(定时器没有运行) 启动定时器
向IP传输报文段
nextseqnum=nextseqnum+length(data)
break;
event2:
重传具有最小序号且仍未应答的报文段
启动定时器
break;
event3:
if(y>sendbase){
sendbase = y;
if(存在未被确认的报文段) 启动定时器
}
break;
}
每当超时重传发生后,TCP都会重传该报文段,并将超时间隔设置为先前值的两倍。这提供了一个形式受限的拥塞控制,避免持续重传分组,导致拥塞更加严重。
超时重传的一个问题是超时周期可能过长,从而增加了端到端的时延。实际上发送方除了超时外,还可以通过注意到冗余ACK来提前重发报文。接收方在一定间隔没有等到新的报文,或是收到了失序的报文,都会发送ACK,如果报文段丢失,那么接收方很可能发送多个冗余ACK。一旦发送方接收到三个冗余ACK,就执行快速重传。采用快速重传,事件三的处理修改如下:
event3:
if(y>sendbase){
sendbase=y;
if(存在未被确认的报文段) 启动定时器
}
else{
对y收到的冗余ACK+1
if(冗余ACK数==3) 重新发送具有序号y的报文段
}
TCP采用的是累积确认的方式,看起来符合GBN可靠传输,但许多TCP实现会将失序但正确的报文缓存起来。TCP接收方也可以有选择的确认,采用类似SR的方式。
5.5 流量控制
接受方接收到报文段后,将报文段存放到接收缓存当中,应用进程从中取出数据。如果应用程序读取的速度较慢,而发送方发送的数据太多太快,就会导致接收缓存溢出。因此TCP提供了流量控制服务,使发送方的发送塑料布与接收方应用程序的读取速率匹配。这与拥塞控制很相似,但是完全是出于不同的原因。
TCP通过让发送方维护一个称为接收窗口的变量来进行流量控制。接收窗口表示接收方可用缓存的大小。发送方需要维护两个变量:
- lastbyteread:读出的最后一个字节
- lastbyterecv:已到达接收缓存的最后一个字节
不允许接收缓存溢出,则lastbyterecv-lastbyteread<=rcvbuffer。则接收窗口为:
r w n d = r c v b u f f e r − [ l a s t b y t e r e c v − l a s t b y t e r e a d ] rwnd=rcvbuffer-[lastbyterecv-lastbyteread] rwnd=rcvbuffer−[lastbyterecv−lastbyteread]
rwnd是一个动态的值。在起始时,rwnd=recvbuffer,此后接收主机会维护该值,并将其发给发送主机,而发送主机需要进行如下的控制:
l a s t b y t e s e n t − l a s t b y t e a c k e d < = r w n d lastbytesent-lastbyteacked<=rwnd lastbytesent−lastbyteacked<=rwnd
为了避免发送主机收到rwnd=0后被阻塞,如果接收窗口为0,发送主机将发送一个只有一个字节的报文段,接收主机将会回发确认,并在确认报文中包含一个新的非0rwnd值。
TCP提供了以上的流量控制服务,UDP是不提供这样的服务的。因此如果使用UDP,进程从缓存中读取报文段的速度不够快,缓存将会溢出,并丢失报文段。
5.6 TCP连接建立和拆除
TCP连接建立的过程如下:
- 第一步:SYN报文段发送。客户端向服务器发送特殊的TCP报文段,其中SYN字段为1,初始序号client_isn随机选择。
- 第二步:SYNACK报文段发送。服务器接收到SYN报文段后,会为连接建立缓存和变量,并向客户发送允许连接的报文段,这个报文段中SYN为1,确认号字段为client_isn+1,服务器的初始序号为随机的server_isn。
- 第三步:收到SYNACK后,客户端也为该连接分配缓存和变量,并发送一个报文给服务器,对允许连接的报文进行确认,确认字段为server_isn+1,SYN=0,此时报文段负载中可以携带数据了。
TCP连接的释放比较简单,客户进程发送一个特殊的报文段,FIN字段为1,服务器接收到后发送确认报文段,此时客户到服务器的TCP连接就关闭了,接下来服务器到客户的TCP连接的关闭也是一样的。客户接收到服务器的FIN报文段后,会进入等待状态,并发送ACK,经过等待后,这个连接就正式关闭了。
6.拥塞控制原理
本节要解决的是网络拥塞的相关问题。包括网络拥塞是如何在上层的服务中体现的,怎样避免网络拥塞,或是至少对它作出反应。
6.1 拥塞原因与代价
通常出现拥塞有以下几种情况:
- 当发送速率超过吞吐量时,平均排队分组数不断增长,源与目的之间的时延也变为无穷大(假设不停发送,有无限大的缓存)。
- 当缓存已满,部分分组被丢弃,这将引起发送方的重传,此外,提前发生超时还可能导致发送方重传没有丢失的分组。
- 在有许多跳的情况下,不同的链路中不同连接的载荷不同。
从以上几种情况来看,由于拥塞丢弃分组产生了以下的代价:
- 分组的到达速率接近链路容量时,分组经历巨大的排队时延
- 发送方必须重传以补偿因为缓存溢出而丢弃的分组
- 发送方在遇到大时延时进行的不必要重传会引起路由器利用链路带宽来转发不必要的分组副本
- 一个分组沿一条路径被丢弃时,每个上游路由器用于转发该分组的传输容量最终被浪费掉了
6.2 拥塞控制方法
拥塞控制方法分为两种:
- 端到端拥塞控制:端系统通过对网络行为(如分组丢失与时延)的观察推断拥塞情况,在端到端进行拥塞控制
- 网络辅助的拥塞控制:路由器向发送方提供关于网络中拥塞状态的显式反馈信息
TCP采用端到端的拥塞控制。
*7.TCP拥塞控制
*7.1 拥塞控制
当出现了网络拥塞时,TCP应该降低发送速率,进行拥塞控制。实现这样的控制,有三个问题需要解决。
- TCP发送方如何感知到与目的地之间的路径上存在拥塞,或是不存在拥塞
- TCP如何限制其向连接上发送流量的速率
- 采用什么算法改变发送速率
下面逐个解决以上的问题。
1.拥塞检测与速率的确定
当发生拥塞时,路径上的路由器缓存溢出,就会引起丢包。对于发送方而言,丢包导致的是出现超时和收到3个冗余ACK。如果发生了这两种情况,就表示发生了拥塞,就应该减小发送速率。这就解决了拥塞检测的问题。在没有拥塞时,为了充分利用所有可用的带宽,TCP发送方还应该可以加快发送的速率。当TCP发送方接收到确认报文段ACK时,就认为一切顺利,网络不拥塞,可以增加发送速率。
2.限制速率
TCP采用了一个拥塞窗口cwnd来限制发送速率。注意这与流量控制相似但是不同。发送方未被确认的数据量不会超过cwnd与rwnd的最小值,即LastByteSent-LastByteAcked<=min{rwnd,cwnd}。由于此处仅探讨拥塞控制,先假设接收缓存无限大,这样发送速率就只与cwnd有关。通过cwnd的值,就可以调整向连接发送数据的速率了。
3.TCP拥塞控制算法
解决了上面两个问题,只要使用特定的算法控制cwnd就可以实现拥塞避免了。TCP拥塞控制算法包括三个部分:慢启动;拥塞避免;快恢复。
- 慢启动
- 起始时,cwnd的值以一个MSS开始,每当一个报文被确认,就增加一个MSS
- 维护一个慢启动阈值ssthresh,当cwnd达到ssthresh,就进入拥塞避免模式
- 出现丢包时,cwnd设置为1,重新开始慢启动,ssthresh值设置为检测到拥塞时的cwnd/2
- 拥塞避免
- 每收到一个确认报文,增加一个MSS
- 发生丢包时,与慢启动的反应相同
- 收到三个冗余ACK时,进入快恢复状态
- 快恢复
- cwnd减半后加上三个MSS,将ssthresh的值减半,进入拥塞避免状态
早期的TCP版本Tahoe没有快恢复机制,无论是收到冗余ACK还是丢包,都直接将cwnd设置为1。TCP的较新版本TCP Reno则加入了快恢复机制。现在已有Reno的许多变种,例如Vegas,该算法在分组发生丢失之前检查源与目的地之间的拥塞,当检测出快要发生的分组丢失时(通过RTT的变化),线性降低发送速率。
7.2 对TCP吞吐量的宏观描述
有了TCP的拥塞控制算法,可以考虑长期存活的TCP连接的吞吐量了。当窗口长度是w,往返时间为RTT,TCP的发送速率大约是W/RTT,在一个窗口内发送了w后,收到前一半发送的分组的ACK,因此发送速率约为W/RTT。不考虑慢开始阶段(指数增长,很快结束),发生丢包时,假设速率减半,再增加到W/RTT。在以上情况下,TCP的速率重复从W/2RTT到W/RTT的过程,在两个值之间线性增长,可以得出一个高度理想化的TCP稳态动态性模型:
一条连接的平均吞吐量 = 0.75 W R T T 一条连接的平均吞吐量 = \frac{0.75W}{RTT} 一条连接的平均吞吐量=RTT0.75W
在高带宽路径中,结合MSS和丢包率L,可以得出一条TCP连接的吞吐量公式:
一条连接的平均吞吐量 = 1.22 M S S R T T L 一条连接的平均吞吐量 = \frac{1.22MSS}{RTT\sqrt{L}} 一条连接的平均吞吐量=RTTL1.22MSS
7.3 公平性
如果有多条TCP连接,通过同一段瓶颈链路,TCP趋于给竞争的多条TCP连接提供平等的带宽共享。书上给出了理想化的证明,在连接有相同MSS和RTT的情况下,公平性是可以保证的。然而现实中这种理想情况并不存在,多媒体应用可以使用UDP连接压制TCP流量,Web浏览器常使用并行连接传输多个对象,带宽的占用并不是公平的。
7.4 明确拥塞通告
拥塞控制的另一类是网络明确向TCP双方发送拥塞信号,这种形式的网络辅助拥塞控制称为明确网络拥塞控制通告ECN。这种形式下,路由器使用一种ECNbit指示该路由器正在经历拥塞,并将该标记携带在IP数据报中,发送给目的主机,再由目的主机告知源主机,实现拥塞控制。