TCP详解(四)

以前的博文中我已经讨论了TCP的可靠传输和TCP的流量控制。这篇博文讨论一下TCP的拥塞控制

TCP拥塞控制

  • 在计算机网络中的链路容量(带宽)、交换结点中的缓存和处理机制,都是网络中的资源。在某段时间,弱队网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏。这种情况就叫做拥塞
  • 想要解决拥塞问题,只解决某一方面的因素是不行的,例如:当某个结点缓存的容量太小时,到达该结点的分组因无存储空间暂存而不得不被丢弃,现在设想将结点的缓存的容量扩展到非常大,于是凡是到该结点的分组均可在该结点的缓存队列中排队,而不受任何限制。但是由于输出链路的容量和处理机的速度并没有提高,因此在这个队列中的绝大多数分组的排队等待时间将会大大的增加,结果上层软件只有将他们重传(因为早就超时了)。因此我们知道简单的扩大结点的容量没有办法解决网络拥塞,甚至会增加网络拥塞的程度。
  • 因此,我们也得出了一个结论,想要解决网络问题,只解决某一个方面的问题,是没有办法解决整个网络拥塞的问题,甚至会加重网络拥塞。因此,在设计拥塞控制策略时,必须全面衡量得失。
拥塞控制和流量控制的分别
  • 拥塞控制和流量控制的关系密切,但是也是由区别的。
  • 拥塞控制就是防止过多的数据注入到网络中,这样可以时网络中的路由器或链路不致过载。拥塞控制所要做的都有一个前台,就是网络能够承受现在的网络负荷。拥塞控制是一个全局性的过程,涉及到所有主机、所有的路由器、以及与降低网络传输性能的所有因素。
  • 流量控制往往是指点对点通信量的控制,是一个端对端的(发送端和接收端),流量控制所要做的就是抑制发送端的发送速率,能够让接收端来得及接收。
  • 某些拥塞控制算法是想发送端发送控制报文,并告诉发送端,网络已经出现了麻烦,必须要放慢速率。这点又和流量控制比较相像。
理想的拥塞控制
  • 具有理想的拥塞控制的网络,在吞吐量饱和之前,网络吞吐量应等于提供的负载,但当提供的负载超过某一限度时,由于网络资源受限,吞吐量不在增长而保持为水平线,即吞吐量达到了饱和。这就表明了提供的负载中有一部分资源损失掉了,虽然如此,在理想的拥塞控制作用下,网络的吞吐量任然维持在其所能达到的最大值。
  • 但是实际的网络情况就很差了,随着提供的负载的增大,网络吞吐量的增长速率逐渐减小。也就是说,在网络吞吐量还未达到饱和时,就已经有一部分的输入分组被丢弃了。当网络的吞吐量明显小于理想的吞吐量时,网络就已经出现了轻度拥塞的状态。当提供的负载达到某一分组数值时,网络的吞吐量反而随着提供的负载大增大而下降,这时网络就进入了拥塞状态。所提供的负载继续增大到某一数值时,网络的吞吐量就下降到零,网路无法工作,这就是所谓的死锁。
拥塞控制的设计
  • 从大的方面来看,可以分为开环控制闭环控制
  • 开环控制:设计网络时事先将有关发生拥塞的因素考虑周到,力求网络在工作时不产生拥塞。但一旦整个系统运行起来,就不再中途进行改正了。
  • 闭环控制:是基于反馈环路的概念,主要有以下几种措施
    • 监测网络系统以便检测到拥塞在何时、何处发生
    • 把拥塞发生的信息传送到可采取行动的地方
    • 调整网络系统的运行以解决出现的问题。
  • 有很多方法可以用来监测网络的拥塞。主要的一些指标是:由于缺少缓存空间而被丢弃的分组的百分数、平均队列长度、超时重传的分组数、平均分组时延、分组时延的标准差等等。上述这些指标的上升都标志着拥塞的增长。
  • 一般在检测到拥塞发生时,要将拥塞发生的信息传送到产生分组的源站。当然,通知拥塞发生的分组同样会使网络更加拥塞。
  • 在路由器转发的分组中保留一个比特或字段,用该比特或字段的值表示网络没有拥塞或产生了拥塞。也可以由一些主机或路由器周期性发出探测分组,以询问拥塞是否发生。
TCP的拥塞控制方式
  • 一共有四种算法,慢开始、拥塞避免、快重传、快恢复。
  • 首先讨论之前,我们假定:1、数据是单方向传送的,对方只传送确认报文。2、接收方总是有足够大的缓存空间,因而发送窗口的大小由网络的拥塞程度来决定
  • 发送方让自己的发送窗口等于拥塞窗口。发送方控制拥塞窗口的原则是:只要网络没有出现拥塞,拥塞窗口就可以再增大一些,以便把更多的分组发送出去,这样就可以提高网络的利用率。但只要网络出现拥塞或者可能出现拥塞,就必须把拥塞窗口减小一点,以减少注入到网络中的分组数,以便缓存网络出现的问题。
  • 现在通信线路的传输质量一般都很好,因传输出差错而丢弃分组的概率是很小的,因此,判断网络拥塞的依据就是出现了超时。
  • 慢开始算法的思路是这样的,当主机开始发送数据时,由于并不清楚网络的负荷情况,所以如果一开始就将大量数据注入到网络,那么就有可能发生网络拥塞。较好的方法是先探测一下,即由小到大逐渐发送窗口,也就是说,由小到大逐渐增大拥塞窗口数值。
  • 慢开始的慢并不是指窗口大小的增长速率慢,而是在TCP开始发送数据报时设置的窗口比较小。
  • 还有一个慢开始门限,我们在之前设置好,当窗口大小小于这个门限时,我们使用慢开始算法,当窗口值大于这个门限时,我们使用拥塞避免算法。
  • 拥塞避免算法就是在拥塞避免阶段,拥塞窗口按线性规律缓慢增长。比慢开始算法的拥塞窗口增长速率缓慢的多。
    在这里插入图片描述
  • 我们从上图可以看出:慢开始门限设置的是16,当执行慢开始算法时,发送方每收到一个对新报文的确认ACK,就把拥塞窗口值加1,然后开始下一轮的传输。因此拥塞窗口随着传输轮次按指数规律增长。当拥塞窗口增长到慢开始门限值时,就改为执行拥塞避免算法,拥塞窗口按线性规律增长。当拥塞窗口代销到24时,网络出现超时,发送方判断为网络拥塞。于是调整门限值减为24的一半12.同时设置拥塞窗口为1,进入慢开始阶段。继续进行上面的操作。
    在这里插入图片描述
  • 我们从上图可以看出:拥塞窗口为24时,出现了一个新情况,就是发送方一连收到3个重复的对同一报文段的重复确认。这是因为采用了快重传算法。
  • 快重传算法可以让发送方尽早知道发生了个别报文段的丢失。快重传算法要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认。即使收到了失序的报文段也要立即发出对已收到报文段的重复确认。
  • 例如:接收方收到了M1和M2后都分别及时发出了确认。先假定接收方没有收到M3却收到了M4,。本来接收方可以什么都不做,但按照快重传算法,接收方必须立即发送对M2的重复确认。以便让发送方及时知道接收方没有收到M3.发送方接着发送M5和M6.接收方收到后任要再次分别发出对M2的重复确认。这样,发送方共收到4次对M2的确认,就知道接收方确认没有收到M3,因而应该立即进行重传,这样就不会出现超时,发送方也就不会误认为出现了网络拥塞。
  • 当发送方知道现在只是丢失了个别的报文段时,于是不启动慢开始。而是执行快恢复算法。这时,发送方调整门限值为此时拥塞窗口值得一半,也就是24的一半12,同时设置拥塞窗口的值为门限值,并开始执行拥塞避免算法。
TCP的拥塞控制的流程图

在这里插入图片描述注意我们在说拥塞控制时假定了接收方总是有足够大的缓存空间,因而发送窗口的大小由网络的拥塞程度来决定,但实际上接收方的缓存空间总是有限的。接收方根据自己的接收能力设定了接收方窗口,并把这个窗口值写入TCP的首部的窗口字段,传送给发送方。因此,接收方窗口又称为通知窗口。因此,从接收方对发送方的流量控制的角度,发送方的发送窗口一定不能超过对方给出的接收方窗口值。那么我们说,发送方窗口的上限应当取为接收方窗口和拥塞窗口这连个变量中较小的一个。

主动队列管理AQM
  • 再来谈谈TCP的拥塞控制和网络层的关系。假定一个路由器对某些分组的处理时间特别长,那么这就可能使这些分组中的数据部分经过很长时间才能达到终点,结果引起发送方对这些报文段的重传。但是重传会使TCP连接的发送端认为在网络中发生了拥塞。于是在TCP的发送端采取了拥塞控制的措施,但实际上网络并没有发生拥塞。
  • 网络层的策略对TCP拥塞控制影响最大的就是路由器的分组丢弃策略。在最简单的情况下,路由器的队列通常都是按照“先进先出”FIFO的规则来处理到来的分组,由于队列长度是非常有限的,因此当队列已满的时候,以后再到达的所有分组都将被丢弃。这就叫做尾部丢弃策略。
  • 尾部丢弃策略的危害:1、使发送方出现超时重传,使TCP进行拥塞控制的慢开始状态。结果使TCP连接的放送方突然把数据的发送速率降低到最小的数值。2、在网络中通常有很多的TCP连接,这些连接中的报文段通常是在复用在网络层的IP数据报中传送。在这种情况下,若发生了路由器中的尾部丢失,就可能会同时影响到很多条TCP连接,结果使这许多TCP连接在同一时间全部进行慢开始状态。这就是所谓的牵一发而动全身。
  • 因此,提出了主动队列管理AQM。所谓“主动”就是不要等到路由器的队列已经达到最大值时才不得不丢弃后面达到的分组。这样太被动了。应当在在队列长度达到某个值要警惕的时候,就主动丢弃所到达的分组。这样就提醒了发送方放慢发送的速率,因而有可能使网络拥塞的程度减轻,甚至不出现网络拥塞。
  • 这里举一个主动管理队列AQM的实现方法:随机早期检测RED。RED需要使路由器维持两个参数,即队列长度最小门限和最大门限,当每一个分组到达时,RED就按照规定的算法先计算当前的平均队列长度。
    • 若平均队列长度小于最小门限,则把新到达的分组放入队列进行排队
    • 若平均队列长度超过最大门限,则把新到达的分组丢弃
    • 若平均队列长度在最小门限和最大门限之间,则按照某一丢弃概率p把新到达的分组丢弃(这就体现了丢弃分组的随机性)
  • RED不是等到已经发生网络拥塞后才把所有在队列尾部的分组全部丢弃,而是在检测到网络拥塞的早期征兆时(即路由器的平均队列长度到达一定数值时),就以概率p丢弃个别分组,让拥塞控制只在个别的TCP连接上进行,因而避免发生全局性的拥塞控制。

TCP的运输连接管理(三次握手和四次挥手)

TCP的连接建立

在这里插入图片描述 - 最初两端的TCP都是处于关闭状态。客户端A主动打开连接,而B被动打开连接。一开始,B的TCP服务器进程先创建传输控制块TCB,准备接受客户进程的连接请求。然后服务器进程就处于listen 监听状态,等待客户的连接请求。

  • A的TCP客户进程也是首先创建传输控制块TCB。然后,在打算建立TCP连接时,向B发送连接请求报文段,这时首部中的同步位SYN=1,同时选择一个初始序号seq=x,TCP规定,SYN数据报(即SYN=1的报文段)不能携带数据,但要消耗一个序号。这时,TCP客户进程进入同步已发送状态。
  • B收到连接请求报文段后,如果同意建立连接,则向A发送确认。在确认报文段中应把SYN和ACK位都置为1,确认号是ack=x+1,同时也为自己选择一个初始序号seq=y。请注意:这个报文段也不能携带数据,但是同样的要消耗一个序号。这时TCP服务器进程进入同步收到状态。
  • TCP客户进程收到B的确认后,还要向B给出确认。确认报文段的ACK置为1,确认号ack=y+1,而自己的序号seq=x+1.TCP规定,ACK报文段可以携带数据。但如果不携带数据则消耗序号,在这种情况下,下一个数据报文段的序号任然是seq=x+1。这时,TCP连接已经建立,A进入ESTABLISHED(已建立连接)状态。
  • 当B收到A的确认后,也进入ESTABLISSHED(已建立连接)状态。
  • 为什么A最后还要发送一次确认呢?
    • 主要是为了防止已失效的连接请求报文段突然又传送给B,因而产生错误。
    • 已失效的连接请求报文段:A发出第一个连接请求报文段在某些网络结点长时间逗留了,以致延误到连接释放以后的某个时间才到达B。本来这是一个失效的报文段。但B收到此失效的连接请求报文段后,就误以为是A又发出一次新的连接请求。于是就向A发出确认报文段,同意建立连接。假定不采用报文握手,那么只要B发出确认,新的连接就建立了。由于现在A并没有发出建立连接的请求,因此不会理睬B的确认,也不会向B发送数据。但B却以为新的运输连接已经建立了,并一直等待A发来数据。B的许多资源就这样白白浪费了。
TCP的连接释放

在这里插入图片描述- 数据传输结束后,通信的双方都可以释放连接。现在A和B都处于已建立连接状态,A的应用程序先向其TCP发出连接释放报文段,并停止再发送数据,主动关闭TCP连接。A把连接释放报文段首部的终止控制位FIN置1,其序列seq=u,它等于前面已传送的数据的最后一个字节的序号加1.这时A进入FIN-WAIT-1(终止等待1)装态,等待B的确认,请注意:FIN报文段即使不携带数据,它也消耗掉一个序号。

  • B收到连接释放报文段后即发出确认,确认号ack=u+1,而这个报文段自己的序号是v,等于B前面已传送过的数据的最后一个字节的序号加1。然后B进入CLOSE-WAIT(关闭等待)状态。TCP服务器进程这时应通知高层应用进程,因而从A到B这个方向的连接就释放了,这时的TCP连接进入了半关闭状态,即A已经没有数据要发送了,但B若发送数据,A任然要接收,也就是说,从B到A这个方向的连接并未关闭,这个状态可能会持续一段时间。
  • A收到来自于B的确认后,就进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。
  • 若B已经没有要向A发送的数据,其应用进程就通知TCP释放连接。这时B发出的连接释放报文段必须使FIN=1.现假定B的序号为w(可能在半关闭状态下B又发送了一些数据)。B还必须重复上次已发送的确认号ack=u+1。这时B就进入LAST-ACK(最后确认)状态,等待A的确认。
  • A收到B的连接释放报文段后,必须对此发出确认,在确认报文段中把ACK置1,确认号ack=w+1,而自己的序号是seq=u+1(FIN报文段要消耗掉一个序号)。然后进入到TIME-WAIT(时间等待)状态。
时间等待计时器
  • 请注意:现在TCP连接还没有被释放掉。必须经过时间等待计时器设置的时间2MSL后,A才进入CLOSED状态。时间MSL叫做最长报文段寿命。TCP允许不同的实现可根据具体情况使用更小的MSL值,建议为2分钟。
  • 为什么要设置这个时间MSL呢?
    • 1、为了保证A发送的最后一个ACK报文段能够到达B,这个ACK报文段有可能丢失,因而使处于LAST-ACK状态的B收不到对已发送的FIN-ACK报文段的确认,B会超时重传这个FIN+ACK报文段,而A就能在2MSL时间内收到这个重传的FIN+ACK报文段。接着A重传一次确认,重新启动2MSL计时器。最后,A和B都正常进入到CLOSED状态,那么就无法收到B重传的FIN+ACK报文段,因而也不会再发送一次确认报文段。
    • 2、防止上一节提到的“已失效的连接请求报文段”出现在本连接中。A在发送完最后一个ACK报文段后,在经过2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个新连接中不会出现这种旧的练级诶请求报文段。
保活计时器
  • 情况:客户已主动与服务器建立了TCP连接。但是后来客户端的主机突然出现了故障。显然,服务器以后就不能再收到客户端发来的数据。因此,应当有措施使服务器不要白白的等待下去。这就要使用保活计时器。服务器每收到一次客户的数据,就重新设置保活计时器,时间的设置是2小时。若两个小时没有收到客户端的数据,服务器就发送一个探测报文段,以后则每隔75秒发送一次。若一连发送10个探测报文段后仍无客户的响应,服务器就认为客户端出了故障,接着就关闭了这个连接。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值