目录
1.停止等待协议
2.连续ARQ协议
3.TCP报文段的首部格式
4.TCP的滑动窗口机制
(1)发送窗口
(2)接收窗口
(3)发送缓存
5.超时重传时间的选择
6.选择确认SACK(Selective ACK)
7.使用滑动窗口实现流量控制
(1) 流量控制原理:编辑
(2)TCP的传输效率:
8.拥塞控制
(1)拥塞控制的基本原理
(2)TCP的拥塞控制方法
(3)发送方判断拥塞的方法
(4)TCP拥塞控制算法
9.主动队列管理AQM
1.停止等待协议
每发送完一个分组就停止发送,等待对方的确认。在收到确认后再发送下一个分组。
A 发送完分组 M1 后就暂停发送,等待 B 的确认 (ACK)。
B 收到 M1 向 A 发送 ACK。
A 在收到了对 M1 的确认后,就再发送下一个分组 M2。
在以下两种情况下B不会向A发送确认信息
1.B接收M1时检测出了差错,就丢失M1,其他什么也不做(不通知A收到有差错的分组)
2.M1在传输过程中丢失。
针对B丢失M1不通知A的问题,A如何知道B是否正确收到M1,答案是超时重传
1.A 为每一个已发送的分组设置一个超时计时器。
2.A 只要在超时计时器到期之前收到了相应的确认,就撤销该超时计时器,继续发送下一个分组 M2。
3.若A在超时计时器规定时间内没有收到 B 的确认,就认为分组错误或丢失,就重发该分组。
4.假定B正确收到A重传的分组M1,B会采取以下两个行动:
(1)丢弃这个重复的分组 M1,不向上层交付。
(2) 向A 发送确认。
如果B发送的确认丢失或迟到怎么办?
1.B 对分组M1的确认迟到了,因此A在超时计时器到期后重传M1。
2.B 会收到重复的 M1,丢弃重复的 M1,并重传确认分组。
3.A 会收到重复的确认。对重复的确认的处理: 丢弃。
针对往返时间RRT:
当往返时间 RTT 远大于分组发送时间 T时,信道的利用率会非常低
所以停止等待协议虽然简单,但是信道利用率很低
总结一下停止等待协议的要点:
•停止等待:发送方每次只发送一个分组。在收到确认后再发送下一个分组
•暂存:在发送完一个分组后,发送方必须暂存已发送的分组的副本,以备重发
•编号:对发送的每个分组和确认都进行编号超时重传。发送方为发送的每个分组设置一个超时计时器。若超时计时器超时位收到确认,发送方会自动超时重传分组
•超时计时器的重传时间应当比数据在分组传输的平均往返时间更长一些防止不必要的重传
•简单,但信道利用率太低
2.连续ARQ协议
为了提高效率提出了连续ARQ协议,其采用流水线传输,即在收到确认之前,发送方连续发出多个分组。
补充:滑动窗口协议和连续ARQ协议一样,都采用流水线传输方式。
ARQ协议有以下几个要点:
•发送窗口: 发送方维持一个发送窗口,位于发送窗口内的分组都可被连续发送出去,而不需要等待对方的确认。
•发送窗口滑动: 发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置
•累积确认: 接收方对按序到达的最后一个分组发送确认,表示:到这个分组为止的所有分组都已正确收到了。
ARQ协议又分为选择重传ARQ和回退ARQ:
回退ARQ
重传方式:当发送方发现有数据丢失或损坏时,会重传从该数据段开始之后的所有未确认的数据段。
选择重传ARQ
重传方式:当发送方发现有数据丢失或损坏时,只会重传丢失或损坏的那个数据段,而不是将后续的数据段全部重传。
实现方法:
1.发送方维持着一个窗口,包含可发送或已发送但未被确认的序号。
2.接收方维持着一个窗口,包含可接收的序号,每个序号还保留一个缓冲区。与每个缓冲区项相关联的还有一个标志位,用来指明缓冲区是满的还是空的。
3.每到达一个帧,接收方通过检查它的序号,看是否落在窗口内。如果确实落在窗口内且之前没有接收过,则接收该分组然后保存在缓冲区并返回一个确认。等前面这些帧都到达后一起交付给上层。
4.发送端每个发送缓冲都设有一个超时一个超时计时器,一个超时事件发生后相应缓冲区的帧就会被重发
但是非顺序接收也引发了一些特殊问题。
假设我们用3bit的序号(0~ 7),那么发送方允许发送8个帧,然后开始等待确认。刚开始时,发送方和接收方的窗口如图所示:
现在发送方发出0~ 7号帧,接收方的窗口接收任何序号落在0~7之间的帧。
这8个帧全部到达后,接收方发送确认(发送方还未收到),并且向前移动它的窗口,允许下一次接收0、1、2、3、4、5,6,7号帧
这时会存在两个场景
情景一:
发送方收到了全部确认,发送窗口前移,然后继续发送后面的数据(0号帧)
这时接收方会收到一个0号帧
情景二:
假如第一次发出的所有确认都丢失了,所以接收方在超时之后便会重传0号帧(其他帧也会重传,只不过0号帧先被发送、先超时、先重传)
因为接收方已经接收了0~7号帧,并已发送了确认(虽然发送方未收到),所以窗口会向前移动,允许下一次接收0、1、2、3、4、5,6,7号帧。
此时接收方也能收到一个0号帧
两种情况下接收方都能收到0号帧,一个是重传的一个是新发送的,接收方没法区分这两个0号帧。
这个问题通常通过设置窗口大小来解决
1.让接收窗口大小等于发送窗口大小(大了会溢出,小了没意义)
2.发送窗口=接收窗口=2^(n-1) ,n表示用多少bit来表示允许发送的帧序号,上文发送了8个帧(2 ^3 ),也就是3bit,所以窗口大小应该小于等于2 ^(3-1)=4,即序列号的一半
————————————————
原文链接:https://blog.csdn.net/aaahuahua/article/details/119965804
3.TCP报文段的首部格式
•源端口和目的端口:各占 2 字节(32位)。端口是运输层与应用层的服务接口运输层的复用和分用功能通过端口实现。
•序号: 占 4 字节。TCP 连接中传送的数据流中的每一个字节都有一个序号。序号字段的值则指的是本报文段所发送的数据的第一个字节的序号
•确认号: 占 4 字节,是期望收到对方的下一个报文段的数据的第一个字节的序号
注:若确认号 = N,则表明: 到序号 N - 1 为止的所有数据都已正确收到
•数据偏移 (即首部长度): 占 4 位,指出 TCP 报文段的数据起始处距离TCP 报文段的起始处有多远。单位是 32 位字 (以 4 字节为计算单位)
•保留:占6位,保留为今后使用,但目前应置为0
•紧急 URG: 控制位:当 URG = 1 时,表明紧急指针字段有效,告诉系统此报文段中有紧急数据,应尽快传送(相当于高优先级的数据)
•确认 ACK: 控制位:只有当 ACK =1 时,确认号字段才有效。当ACK =0 时,确认号无效。
•推送 PSH (PuSH)控制位:接收 TCP 收到 PSH = 1 的报文段后就尽快 (即“推送”向前)交付接收应用进程,而不再等到整个缓存都填满后再交付。
•复位 RST(ReSet): 控制位。当 RST=1 时,表明 TCP 连接中出现严重差错(如主机崩溃或其他原因)必须释放连接,然后再重新建立运输连接。
•同步 SYN (SYNchronization): 控制位。同步 SYN = 1 表示这是一个连接请求或连接接受报文。当 SYN = 1,ACK = 0时,表明这是一个连接请求报文段。当 SYN = 1,ACK = 1 时,表明这是一个连接接受报文段。
•终止 FIN (Finish): 控制位。用来释放一个连接。FIN=1 表明此报文段的发送端的数据已发送完毕,并要求释放运输连接。
•窗口: 占2 字节。窗口值告诉对方: 从本报文段首部中的确认号算起,接收方目前允许对方发送的数据量 (以字节为单位)
注:窗口字段明确指出了现在允许对方发送的数据量。窗口值经常在动态变化。
•检验和:占 2 字节。检验和字段检验的范围包括首部和数据这两部分在计算检验和时,要在 TCP 报文段的前面加上 12 字节的伪首部。
在计算检验和时,临时把 12 字节的“伪首部”和 TCP 报文段连接在一起。伪首部仅仅是为了计算检验和。
紧急指针:占2 字节。在 URG =1时,指出本报文段中的紧急数据的字节数(紧急数据结束后就是普通数据),指出了紧急数据的末尾在报文段中的位置。
选项:长度可变,最长可达40个字节。
TCP的选项字段包括很多内容,这里只讲主要的,如果想详细了解:http://t.csdnimg.cn/UIb7P
•选项(2)最大报文段长度MSS
MSS(Maximum Segment Size)是 TCP 报文段中的数据字段的最大长度,数据字段加上 TCP 首部才等于整个的 TCP 报文段所以,MSS是“TCP 报文段长度减去 TCP 首部长度。这个数据字段与接收窗口值没有关系。
对于MSS有以下要求:
•不能太小:网络利用率降低。例如:仅 1 个字节。利用率就不会超过1/41。
•不能太大:开销增大,IP 层传输时要分片,终点要装配。分片传输出错时,要整个分组。
•满足IP 层传输时不再分片。默认值= 536字节,报文段长度 = 536 + 20 =556 字节,IP 数据报长度 = 556 + 20 = 576 字节
•选项(3)窗口扩大
窗口扩大选项: 占3 字节,其中一个字节表示移位值 S。
新的窗口值位数从 16 增大到(16 + S),相当于把窗口值向左移动 S 位。移位值允许使用的最大值是 14,窗口最大值增大到 2的(16 + 14)次方 - 1= 2的(30)次方 - 1。窗口扩大选项可以在双方初始建立TCP 连接时进行协商。
•选项(8)时间戳
占10 字节。最主要的 2个字段时间戳值字段 (4字节)和时间戳回送回答字段 (4字节)
2个主要功能:
1.计算往返时间 RTT
2.防止序号绕回 PAWS(Protect Against Wrapped Sequencenumbers)
序号重复时,为了使接收方能够把新报文段和迟到很久的旧报文段区分开,可以在报文段中加上时间戳。
填充:使整个TCP首部长度使4字节的整数倍。
4.TCP的滑动窗口机制
(1)发送窗口
•A 根据 B 给出的窗口值,构造出自己的发送窗口。
•发送窗口里面的序号表示允许发送的序号。
•窗口越大,发送方就可以在收到对方确认之前连续发送更多的数据,因而可能获得更高的传输效率。
发送窗口包含的内容:
假定A发送了序号为31~41共11个字节的数据。
P1= 后沿,P2 = 当前,P3= 前沿
P3-P1=A的发送窗口 (又称为通知窗口)
P2-P1=已发送但尚未收到确认的字节数
P3- P2=允许发送尚未发送的字节数 (又称为可用窗口)
(2)接收窗口
B 收到了序号为32和33的数据,但未收到序号为 31的数据,因此,因此发送的确认报文段中的确认号是 31 (即期望收到的序号)
(3)窗口滑动
确认号为31,表示31之前的数据已发送并收到确认
由于32和33数据确认接收,但是未收到序号31的数据,所以接收方的序号为31,表示期望收到31
接收方的滑动窗口前移
发送窗口继续发送,粉色框代表已发送未确认
发送窗口未收到确认,有两种可能:
1.B未发送
2.B已经发送,但是未到达A
此时,为保证可靠传输:
A 只能认为 B 还没有收到这些数据。A 经过一段时间后 (由超时计时器控制)就重传这部分数据,重新设置超时计时器,直到收到 B 的确认为止。
如果 A 按序收到落在发送窗口内的确认号,就使发送窗口向前滑动,并发送新的数据。
(3)发送缓存
可以看到发送窗口只是发送缓存的一部分:
图中的发送应用程序即发送方的应用程序把字节流写入TCP发送缓存(不能太快,否则发送缓存会溢出)
TCP发送缓存中暂存着:
(1)发送应用程序传送给发送方 TCP准备发送的数据。
(2) TCP 已发送出但尚未收到确认的数据。
发送缓存中的字节数=发送应用程序最后写入缓存的字节-最后被确认的字节
(4)接收缓存
这里的接收应用程序即:接收方的应用程序从TCP接收缓存中读取尚未被读取的字节。
接收缓存暂时存放着:
(1)按序到达的、但尚未被接收应用程序读取的数据;
(2)未按序到达的数据。
注:若不能及时读取,缓存最终会被填满,使接收窗口减小到零。如果能够及时读取,接收窗口就可以增大,但最大不能超过接收缓存的大小。
对发送方和接收方需要注意:
(1)发送窗口是根据接收窗口设置的,但在同一时刻,发送窗口并不总是和接收窗口一样大(因为有一定的时间滞后)。
(2)TCP 标准没有规定对不按序到达的数据应如何处理。通常是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付上层的应用进程。
(3)TCP 要求接收方必须有累积确认的功能,以减小传输开销。接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息顺便捎带上。但接收方不应过分推迟发送确认,否则会导致发送方不必要的重传,捎带确认实际上并不经常发生。
5.超时重传时间的选择
重传时间的选择是一个比较复杂的问题。TCP采用了一种自适应算法,它记录一个报文段发出的时间,以及收到相应确认的时间。
这两个时间之差就是报文段的往返时间RTT。
•加权平均往返时间。又称为平滑的往返时间
其中,0a1,若 a-->0,表示 RTT 值更新较慢。若a-->1,表示RTT 值更新较快。
RFC 6298推荐的a值为1/8,即0.125
•是偏差的加权平均值
其中:b是个小于1的系数,其推荐值是 1/4,即 0.25
•超时重传时间RTO,应略大于加权平均往返时间。
超时重传报文段后,如何判定此确认报文段是对原来的报文段的确认还是对重传报文段的确认?
(1)Karn算法:
通过不采用重传报文段的往返时间样本,Karn算法可以避免对丢失或延迟的报文段进行误判,从而更准确地计算平均往返时间。
算法原理:
•在发送方发送一个报文段后,它会启动一个计时器来测量往返时间(RTT),即发送方发送报文段到接收方收到确认消息之间的时间。
•如果发送方在计时器超时之前收到了确认消息,说明报文段成功到达接收方,并且RTT可以被准确测量。发送方将测量到的RTT样本纳入平均值的计算中。
•如果发送方在计时器超时后才收到确认消息,说明报文段丢失或延迟较大。由于无法准确测量这个丢失或延迟的报文段的RTT,为了避免错误地计算平均值,Karn算法不采用该报文段的往返时间样本。
但会出现新的问题:
当报文段的时延突然增大很多时,在原来得出的重传时间内不会收到确认报文段,于是就重传报文段。但根据 Karn 算法,不考虑重传的报文段的往返时间样本。这样,超时重传时间就无法更新造成很多不必要的重传。
(2)修正的Karn算法:
报文段每重传一次,就把 RTO 增大一些
系数y的典型值 =2
当不再发生报文段的重传时,才根据报文段的往返时延更新平均往返时延RTT和超时重传时间 RTO的数值。
6.选择确认SACK(Selective ACK)
若收到的报文段无差错,只是未按序号,中间还缺少一些序号的数据,那么只传送缺少的数据而不重传已经正确到达接收方的数据。
对于SACK要注意:
如果要使用选择确认,在建立TCP 连接时,要在TCP首部的选项中加上允许 SACK 选项且双方必须事先商定好。
如果使用选择确认,原来首部中的确认号的用法仍然不变(累积确认)。只是在TCP 首部中都增加了 SACK 选项,以便报告收到的不连续的字节块的边界。
注:左边界=第一个字节的序号,右边界=最后一个字节序号+1
例如:SACK报告需重传数据的左边界和有边界
7.使用滑动窗口实现流量控制
(1) 流量控制原理:
但是也可能发生死锁:
B在告诉A接收窗口大小时,报文丢失
这时就需要持续计时器
持续计时器 (persistence timer): 只要 TCP 连接的一方收到对方的零窗口通知,就启动该持续计时器。
•若持续计时器设置的时间到期,就发送一个零窗口探测报文段 (仅携带1字节的数据),对方在确认这个探测报文段时给出当前窗值。
•若窗口仍然是零,收到这个报文段的一方就重新设置持续计时器。
•若窗口不是零,则死锁的僵局就可以打破了。
(2)TCP的传输效率:
应用进程把数据传送到 TCP 的发送缓存后,剩下的发送任务就由TCP来控制了。可以用不同的机制来控制 TCP 报文段的发送时机。例如,第一种机制是 TCP维持一个变量,它等于最大报文段长度 MSS,只要缓存中存放的数据达到MSS字节时,就组装成一个TCP 报文段发送出去。第二种机制是由发送方的应用进程指明要求发送报文段,即TCP 支持的推送(push)操作。第三种机制是发送方的一个计时器期限到了,这时就把当前已有的缓存数据装入报文段(但长度不能超过MSS)发送出去。
但是,如何控制TCP发送报文段的时机仍然是一个较为复杂的问题。例如,一个交互式用户使用一条TELNET连接(运输层为TCP协议)。假设用户只发1个字符,加上20字节的首部后,得到21字节长的TCP 报文段。再加上20字节的IP首部形成41字节长的IP数据报。在接收方TCP立即发出确认,构成的数据报是40字节长(假定没有数据发送)。若用户要求远地主机回送这一字符,则又要发回41 字节长的 IP 数据报和40字节长的确认IP 数据报。这样,用户仅发1个字符时,线路上就需传送总长度为162字节共4个报文段。当线路带宽并不富裕时,这种传送方法的效率的确不高。因此应适当推迟发回确认报文,并尽量使用捎带确认的方法。
在TCP的实现中广泛使用 Nagle 算法。算法如下:若发送应用进程把要发送的数据逐个字节地送到 TCP的发送缓存,则发送方就把第一个数据字节先发送出去,把后面到达的数据字节都缓存起来。当发送方收到对第一个数据字符的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去,同时继续对随后到达的数据进行缓存。只有在收到对前一个报文段的确认后才继续发送下一个报文段。当数据到达较快而网络速率较慢时,用这样的方法可明显地减少所用的网络带宽。Nagle 算法还规定,当到达的数据已达到发送窗口大小的一半或已达到报文段的最大长度时,就立即发送一个报文段。这样做,就可以有效地提高网络的吞吐量。
另一个问题叫作糊涂窗口综合征(silly windowsyndrome),有时也会使TCP的性能变坏。设想一种情况:TCP接收方的缓存已满,而交互式的应用进程一次只从接收缓存中读取1个字节(这样就使接收缓存空间仅腾出1个字节),然后向发送方发送确认,并把窗口设置为1个字节(但发送的数据报是40字节长)。接着,发送方又发来1个字节的数据(请注意发送方发送的IP数据报是 41字节长)。接收方发回确认,仍然将窗口设置为1个字节。这样进行下去,使网络的效率很低。
每次只读取一个字节:
要解决这个问题,可以让接收方等待一段时间,使得或者接收缓存已有足够空间容纳一个最长的报文段,或者等到接收缓存已有一半空闲的空间。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知当前的窗口大小。此外,发送方也不要发送太小的报文段,而是把数据积累成足够大的报文段,或达到接收方缓存的空间的一半大小。
上述两种方法可配合使用。使得在发送方不发送很小的报文段的同时,接收方也不要在缓存刚刚有了一点小的空间就急忙把这个很小的窗口大小信息通知给发送方。
8.拥塞控制
(1)拥塞控制的基本原理
在某段时间,若对网络中某资源的需求超过了该资源所能提供的可用部分,网络的性能就要明显变坏,整个网络的吞吐量将随输入负荷的增大而下降。这种现象称为拥塞(congestion)。
最坏结果则系统崩溃。
拥塞控制产生的条件
可能是因为:
1.节点缓存容量太小;
2.链路容量不足;
3.处理机处理速率太慢;
4.拥塞本身会进一步加剧拥塞。
注:增加资源不能解决拥塞:
1.增大缓存,但未提高输出链路的容量和处理机的速度,排队等待时间将会大大增加,引起大量超时重传,解决不了网络拥塞。
2.提高处理机处理的速率会将瓶颈转移到其他地方;
3.拥塞引起的重传并不会缓解网络的拥塞,反而会加剧网络的拥塞。
(2)TCP的拥塞控制方法
TCP 采用基于滑动窗口的方法进行拥塞控制,TCP 发送方维持一个拥塞窗口 cwnd (Congestion Window)拥塞窗口的大小取决于网络的拥塞程度,并且是动态变化的。发送端利用拥塞窗口根据网络的拥塞情况调整发送的数据量发送窗口大小不仅取决于接收方窗口,还取决于网络的拥塞状况
真正的发送窗口值:
发送窗口的数值不能超过接收窗口和拥塞窗口中的较小的一个。接收窗口的大小体现了接收端对发送端施加的流量控制,而拥塞窗口的大小则是整个互联网的负载情况对发送端施加的拥塞控制。因此,当接收窗口小于拥塞窗口时,发送窗口的大小取决于流量控制,即取决于接收端的接收能力。但当拥塞窗口小于接收窗口时,则发送窗口的大小取决于拥塞控制,即取决于整个网络的拥塞状况。
•当rwnd<cwnd 时,是接收方的接收能力限制发送窗口的最大值。
•当cwnd <rwnd 时,是网络拥塞限制发送窗口的最大值。
控制窗口变化的原则:
•只要网络没有出现拥塞,拥塞窗口就可以再增大一些,以便把更多的分组发送出去,提高网络的利用率。
•但只要网络出现拥塞或有可能出现拥塞,就必须把拥塞窗口减小-些,以减少注入到网络中的分组数,缓解网络出现的拥塞。
(3)发送方判断拥塞的方法
超时重传计时器超时:网络已经出现了拥塞
收到 3 个重复的确认:预示网络可能会出现拥塞
注:因传输出差错而丢弃分组的概率很小 (远小于1 %)因此,发送方在超时重传计时器启动时,就判断网络出现了拥塞。
(4)TCP拥塞控制算法
•慢开始(slow-start)
•拥塞避免(congestion avoidance)
•快重传(fast retransmit)
•快恢复(fast recovery)
慢开始算法和拥塞避免:
发送方维护一个叫做拥塞窗口cwnd的状态变量其值取决于网络的拥塞程度,并且动态变化
•拥塞窗口cwnd的维护原则:只要网络没有出现拥塞,拥塞窗口就再增大一些;但只要网络出现拥塞,拥塞窗口就减少一些
•判断出现网络拥塞的依据: 没有按时收到应当到达的确认报文 (即发生超时重传)
发送方将拥塞窗口作为发送窗口swnd,即swnd = cwnd
维护一个慢开始门限ssthresh状态变量:
•当cwnd<ssthresh时,使用慢开始算法;
•当cwnd>ssthresh时,停止使用慢开始算法而改用拥塞避免算法;
•当cwnd=ssthresh时,既可以使用慢开始算法,也可以拥塞避免算法;
(1)在TCP双方建立逻辑连接关系时,拥塞窗口的值被设置为1,并设置慢开始门限的初始值,这里采用16。
(2)在进行慢开始算法时,发送方每接收到一个对新报文段的确认时,就把拥塞窗口值大小加倍,并开始下一轮的传输。
(3)当拥塞窗口值增长到慢开始门限值时,就改用拥塞避免算法,由于发送方当前的拥塞窗口值是1,而发送窗口值=拥塞窗口值,因此发送方此时只能发送一个TCP报文段。即,拥塞窗口值是几,就能发送几个数据报文段。
现在我们通过展现拥塞窗口随传输轮次的变化来理解:
传输轮次:
发送方给接收方发送数据报文后,接收方给发送方发回相应的确认报文段,一个传输轮次所经历的时间其实就是往返时间。
注:往返时间并非是恒定的数值,使用传输轮次是为了强调把拥塞窗口所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个报文段的确认。
步骤一:
发送方到收到确认后,将拥塞窗口值+1(此时窗口值为2),这样拥塞窗口就可以发送2个数据报文段,当发送方收到2个报文段的确认后,将窗口值+2(2+2=4),接下来就可以发送4个数据报文段,以此类推....即拥塞窗口值为2,4,8,16
步骤二:
现在增大到了慢开始门限值,改用拥塞避免算法:
每个传输轮次结束后,拥塞窗口值只能线性+1,发送方给接收方发送17个数据报文段,若收到接收方返回的确认后,继续线性+1
如图所示:
步骤三:
当拥塞窗口为24时,若发送的数据报部分丢失,发送方就会对这些报文段进行超时重传,
并且确定网络出现拥塞,做一下操作:
1.ssthresh值更新为发生拥塞时cwnd值的一半(注:ssthresh = max (cwnd/2,2)),如图则为12
2.将拥塞窗口值减小为1,并重新开始慢开始算法,当拥塞窗口达到新的门限值时,则改用拥塞避免算法
注:
1.慢开始是指一开始向网络注入的报文段少,并不是指拥塞窗口cwnd增长速度慢
2.“拥塞避免”并非指完全能够避免拥塞,而是指在拥塞避免阶段将拥塞窗口控制为按线性规律增长,使网络比较不容易出现拥塞。
快重传和快恢复:
有时,个别报文段会在网络中丢失,但实际上网络并未发生拥塞这将导致发送方超时重传,并误认为网络发生了拥塞。于是发送方将拥塞窗口减少为1,并错误地启动慢开始算法,因而降低了传输效率。
快重传:
所谓快重传,就是使发送方尽快进行重传,而不是等超时重传计时器超时再重传,采用快重传算法可以让发送方尽早知道发生了个别报文段的丢失。
这就要求接收端:
•接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认;
•即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。
•发送方一旦收到3个连续的重复确认,就将相应的报文段立即重传,而不是等该报文段的超时重传计时器超时再重传。
这样就不会造成对报文3的超时重传,而是提早进行了重传,对于个别丢失的报文段,发送方不会出现超时重传,也就不会误认为出现了拥塞(进而降低拥塞窗口cwnd为1)。使用快重传可以使整个网络的吞吐量提高约20%
快恢复:
发送方一旦收到3个重复确认,就知道现在只是丢失了个别的报文段。于是不启动慢开始算法,而执行快恢复算法。
•发送方将慢开始门限ssthresh值和拥塞窗口cwnd值调整为当前窗口的一半; 开始执行拥塞避免算法•也有的快恢复实现是把快恢复开始时的拥塞窗口cwnd值再增大一些,即等于新的ssthresh + 3。既然发送方收到3个重复的确认,就表明有3个数据报文段已经离开了网络;这3个报文段不再消耗网络资源而是停留在接收方的接收缓存中;可见现在网络中不是堆积了报文段而是减少了3个报文段。因此可以适当把拥塞窗口扩大些。
例题:
一个TCP连接总是以1KB的最大段长发送TCP段,发送方有足够多的数据要发送。当拥塞窗口为16KB时发生了超时,如果接下来的4个RTT(往返时间)内的TCP段的传输都是成功的,那么当第4个RTT时间内发送的所有TCP段都得到肯定应答时,拥塞窗口大小是(9KB)
9.主动队列管理AQM
TCP 拥塞控制和网络层采取的策略有密切联系。
例如,假定一个路由器对某些分组的处理时间特别长,那么这就可能使这些分组中的数据部分(即 TCP 报文段)经过很长时间才能到达终点,结果引起发送方对这些报文段的重传。根据前面所讲的,重传会使 TCP 连接的发送端认为在网络中发生了拥塞。于是在TCP的发送端就采取了拥塞控制措施,但实际上网络并没有发生拥塞。
FIFO(先进先出)
网络层的策略对TCP拥塞控制影响最大的就是路由器的分组丢弃策略。在最简单的情况下,路由器的队列通常都按照“先进先出”FIFO(First In First Out)的规则处理到来的分组。由于队列长度总是有限的,因此当队列已满时,以后再到达的所有分组(如果能够继续排队,这些分组都将排在队列的尾部)将都被丢弃。这就叫作尾部丢弃策略。
若路由器进行了尾部丢弃,所有到达的分组都被丢弃,不论它们属于哪个TCP连接。
路由器的尾部丢弃往往会导致一连串分组的丢失,这就使发送方出现超时重传,使TCP进入拥塞控制的慢开始状态,结果使TCP连接的发送方突然把数据的发送速率降低到很小的数值。
全局同步
更为严重的是,在网路中通常有很多的 TCP 连接(它们有不同的源点和终点)。这些连接中的报文通常是复用在网络层的 IP 数据报中传送的。在这种情况下,若发生了路由器中的尾都丢弃,就可能会同时影响到很多条 TCP 连接,结果使这许多 TCP 连接一时间突然都进入到慢开始状态。这在 TCP 的术语中称为全局同步(lobal synchronization),全局同步使得全网的通信量突然下降了很多,而在网络恢复正常后,其通信量又突然增大很多。
为了避免发生网络中的全局同步现象,提出了主动队列管理AQM (ACti多。Queue Management)。所谓“主动”就是不要等到路由器的队列长度已经达到最大值时才不得不丢弃后面到达的分组。这样就太被动了。应当在队列长度达到某个值得警惕的数值(即当网络拥塞有了某些拥塞征兆时),就主动丢弃到达的分组。这样就提醒了发送方放慢发送的速率,因而有可能使网络拥塞的程度减轻,甚至不出现网络拥塞。
AQM 可以有不实现方法,其中曾流行多年的就是随机早期检测RED(Random Early Detection)。RED还几个不同的名称,如Random EarlyDrop或Random Early Discard(随机早期丢弃)。
实现 RED时需要路由器队列维持两个参数:
队列长度最小门限 THmin
队列长度最大门限THmax。
RED 对每一个到达的分组都先计算平均队列长度 。
1.若平均队列长度小于最小门限 THmin,则将新到达的分组放入队列进行排队。
2.若平均队列长度超过最大门限 THmax则将新到达的分组丢弃。
3.若平均队列长度介于在最小门限 THmin和最大门限 THax 之间则按照某一概率 p 将新到达的分组丢弃。
由此可见,RED不是等到已经发生网络拥塞后才把所有在队列尾部的分组全部丢弃,而是在检测到网络拥塞的早期征兆时(即路由器的平均队列长度达到一定数值时),就以概率p丢弃个别的分组,让拥塞控制只在个别的 TCP连接上进行,因而避免发生全局性的拥塞控制。
在RED的操作中,最难处理的就是丢弃概率p的选择,因为p并不是个常数。对每个到达的分组,都必须计算丢弃概率p的数值。IETF曾经推荐在互联网中的路由器使用RED机制[RFC2309],但多年的实践证明,RED的使用效果并不太理想。因此,在2015年公布的RFC7567已经把过去的RFC2309列为“陈旧的”,并且不再推荐使用 RED。对路由器进行主动队列管理 AQM 仍是必要的。AQM 实际上就是对路由器中的分组排队进行智能管理,而不是简单地把队列的尾部丢弃。现在已经有几种不同的算法来代替旧的 RED,但都还在实验阶段。目前还没有一种算法能够成为IETF 的标准。