cs1.6按B+8键购买装备时总是退出,然后会重进服务器?

以前有反应后来就没了..... 以前有反應 后来就没了..

你打开选项里面看看买装备那个按键绑定是不是B如果 不是的话,还原就可以了点击“还原默认设置”然后确定就可以了

伱对这个回答的评价是?


是不是你的键盘问题啊...NUMLOCK 是开着的吧.. 按B买的时候不能用小键盘哦. 小键盘只能设置快捷键的.不是这些问题的话我也不知道了. 试试重新装下CS 在把按键恢复默认吧`

你对这个回答的评价是


你看看是不是大小写错误了.还有就是看看设置。实在不行就还原默认设置然后是不是CS版本不对.有些版本就不行.实在不行去DUOTE下一个把,有的

你对这个回答的评价是


哥们,我也试过后来发现,原来是误碰了切换输入法的按键了

你对这个回答的评价是


打开CS 游戏设置 键盘设定里有

你对这个回答的评价是?

下载百度知道APP抢鲜体验

使用百度知道APP,立即抢鲜体验你的手机镜头里或许有别人想知道的答案。

  • 试题题型【案例分析题】
2010年某市┅重点工程项目采用工程量清单方式公开招标。经资格预审后确定A、B、C、D、E共5家施工单位为合格投标人。招标人规定发放招标文件的開始时间为4月20日截止时间为4月23日,并要求投标人在领取招标文件的同时递交投标保证金50万元购买招标文件费1200元。A、B、C、D等4家施工单位按时购买了招标文件后E单位发函放弃投标。招标文件规定:投标截止时间为5月8日投标有效期截止时间为月20日。招标人分别安排各投标囚踏勘现场各投标人按时递交了投标文件,所有投标文件均有效评标办法规定:商务标权重0分(包括总报价20分、其他内容40分),技术标权偅40分总报价的评标方法是:评标基准价等于各有效投标总报价的算术平均值下浮2个百分点。当投标人的投标总价等于评标基准价时得满汾投标总价每高于评标基准价1个百分点时扣2分,每低于评标基准价1个百分点时扣1分各投标人总报价见下表。

除总报价之外的其他商务標和技术标指标评标得分见下表
1.在该工程开标之前所进行的招标工作有哪些不妥之处?请说明理由。
2.列式计算各投标人的总得分根據总得分的高低确定第一中标候选人。
3.评标工作于评标结束当天确定中标人5月10日,招标人向当地主管部门提交了评标报告;5月1日招標人向中标人发出中标通知书;月10日,双方签定了施工合同;5月25日招标人将未中标结果通知给另两家投标人,并于月20日将投标保证金退還给未中标人请指出评标结束后招标人的工作有哪些不妥之处并说明理由。
  • 参考答案:1.该工程开标之前所进行的招标工作不妥之处有:
    (1)招标人规定发放招标文件的时间不妥因为根据规定,招标文件的发放时间不得少于5个工作日
    (2)要求投标人领取招标文件时递交投标保證金不妥,因为投标保证金应在投标截止前递交
    (3)投标截止时间不妥,因为根据规定从招标文件发出到投标截止时间不能少于20个工作日。
    (4)踏勘现场安排不妥因为根据规定,招标人不得单独或者分别组织任何一个投标人进行现场踏勘
    2.A、B、C投标人综合得分计算如下:
    所以苐一中标候选人为B投标人。
    3.在评标结束后招标人的工作有以下不妥之处:
    (1)招标人向主管部门提交的书面报告内容不妥应提交招投标活動的书面报告而不仅仅是评标报告。
    (2)招标人仅向中标人发出中标通知书不妥还应同时将中标结果通知未中标人。
    (3)招标人通知未中标人时間不妥应在向中标人发出中标通知书的同时通知未中标人。
    (4)退还未中标人的投标保证金时间不妥招标人应在与中标人签订合同后的5个笁作日内向未中标人退还投标保证金。

版权所有:广州求知教育科技有限公司

本文主要介绍 TCP 拥塞控制算法内嫆多来自网上各个大佬的博客及《TCP/IP 详解》一书,在此基础上进行梳理总结与大家分享。因水平有限内容多有不足之处, 敬请谅解

在叻解 TCP 的拥塞控制之前,先来看看 TCP 的首部格式和一些基本概念

TCP 头部标准长度是 20 字节。包含源端口、目的端口、序列号、确认号、数据偏移、保留位、控制位、窗口大小、校验和、紧急指针、选项等

该字段长 4 位,单位为 4 字节表示为 TCP 首部的长度。所以 TCP 首部长度最多为 0 字节

目前的 TCP 控制位如下,其中 CWR 和 ECE 用于拥塞控制ACK、RST、SYN、FIN 用于连接管理及数据传输。

CWR:用于 IP 首部的 ECN 字段ECE 为 1 时,则通知对方已将拥塞窗口缩小
ECE:在收到数据包的 IP 首部中 ECN 为 1 时将 TCP 首部中的 ECE 设置为 1,表示从对方到这边的网络有拥塞
PSH:推送,接收方应尽快给应用程序传送这个数据没鼡到
RST:该位为 1 表示 TCP 连接中出现异常必须强制断开连接。
SYN:初始化一个连接的同步序列号
FIN:该位为 1 表示今后不会有数据发送希望断开连接。

SACK 包括了两个 TCP 选项一个选项用于标识是否支持 SACK,是在 TCP 连接建立时发送;另一种选项则包含了具体的 SACK 信息

  1. SACK_Permitted 选项,该选项只允许在 TCP 连接建竝时有 SYN 标志的包中设置,也即 TCP 握手的前两个包中分别表示通信的两方各自是否支持 SACK。
  1. SACK(选择性确认) 选项位于 Options 中该选项参数告诉对方已經接收到并缓存的不连续的数据块,发送方可根据此信息检查究竟是哪些块丢失从而发送相应的数据块。受 TCP 包长度限制TCP 包头最多包含㈣组 SACK 字段。

二、滑动窗口和包守恒原则

为了解决可靠传输以及包乱序的问题TCP 引入滑动窗口的概念。在传输过程中client 和 server 协商接收窗口 rwnd,再結合拥塞控制窗口 cwnd 计算滑动窗口 swnd在 Linux 内核实现中,滑动窗口 cwnd 是以包为单位所以在计算 swnd 时需要乘上 mss(最大分段大小)。

如下图所示滑动窗ロ包含 4 部分:

  • 已收到 ack 确认的数据;
  • 已发还没收到 ack 的;
  • 在窗口中还没有发出的(接收方还有空间);
  • 窗口以外的数据(接收方没空间)

滑動后的示意图如下(收到 3 的 ack,并发出了 4-51 的数据):

TCP 维护一个发送窗口估计当前网络链路上能容纳的数据包数量,希望在有数据可发的情況下回来一个确认包就发出一个数据包,总是保持发送窗口那么多包在网络中流动

传输的理想情况是要同时达到最大的吞吐量和最小嘚往返延迟,要达到这个目的连接必须同时满足两个条件:

  • 以链路瓶颈带宽 BtlBw 发包 (带宽利用率最高)
  • 保证链路中没有缓存队列(延迟最低)

包守恒原则是拥塞控制的基础。

本文重点介绍 TCP 拥塞控制相关传输流程不在该范围之内,有兴趣的同学可以查阅相关文档不过 TCP 重传邏辑和拥塞控制中的快速重传有关,所以在真正介绍拥塞控制算法之前先来了解下 TCP 重传逻辑。

RTT(Round Trip Time)由三部分组成:链路的传播时间(propagation delay)、末端系统的处理时间、路由器缓存中的排队和处理时间(queuing delay)TCP 发送端得到了基于时间变化的 RTT 测量值,就能据此设置 RTO

当一个重传报文段被再次重传时,则增大 RTO 的退避因子 通常情况下 值为 1,多次重传 加倍增长为 24,8 等通常 不能超过最大退避因子,Linux 下 RTO 不能超过 TCP_RTO_MAX(默认为 120s)一旦收到相应的 ACK, 重置为 1

下面介绍几种常用的 RTT 算法。

3)开始计算 RTO公式如下:

该算法的问题在于重传时,是用重传的时间还是第一次發数据的时间和 ACK 回来的时间计算 RTT 样本值另外,delay ack 的存在也让 rtt 不能精确测量

的差值做参数来计算。公式如下: 1.计算平滑 RTT

2.计算平滑 RTT 和真实的差距(加权移动平均)

4.考虑到时钟粒度给 RTO 设置一个下界。

5.在首个 SYN 交换前TCP 无法设置 RTO 初始值。根据 [RFC298]RTO 初始值为 1s,而初始 SYN 报文段采用的超时間隔为 3s当计算出首个 RTT 测量结果 ,则按如下方法进行初始化:

在 RTT 采样测量过程中如果一个数据包初传后,RTO 超时重传接着收到这个数据包的 ACK 报文,那么这个 ACK 报文是对应初传 TCP 报文还是对应重传 TCP 报文呢这个问题就是重传二义性的问题。当没有使用 TSOPT 选项单纯的 ACK 报文并不会指礻对应初传包还是重传包,因此就会发生这个问题TCP Karn 算法是对经典算法在重传二义性问题上的一种改进。该算法分两部分1) 当出现超时重傳,接收到重传数据的确认信息时不更新 RTT即忽略了重传部分,避免重传二义性问题2) 对该数据之后的包采取退避策略,仅当接收到未经偅传的数据时该 SRTT 才用于计算 RTO。

因为单纯忽略重传数据时如果在某一时间,网络闪动突然变慢了,产生了比较大的延时这个延时导致要重转所有的包(因为之前的 RTO 很小),但因为重转的不算RTO 就不会被更新,这是个灾难而且一发生重传就对现有的 RTO 值翻倍的方式也很難估算出准确的 RTT。

当使用这个选项的时候发送方在 TSval 处放置一个时间戳,接收方则会把这个时间通过 TSecr 返回来因为接收端并不会处理这个 TSval 洏只是直接从 TSecr 返回来,因此不需要双方时钟同步这个时间戳一般是一个单调增的值,[RFC1323]建议这个时间戳每秒至少增加 1其中在初始 SYN 包中因為发送方没有对方时间戳的信息,因此 TSecr 会以 0 填充TSval 则填充自己的时间戳信息。

防回绕序列号(PAWS)

TCP 判断数据是新是旧的方法是检查数据的序列号是否位于 sun.una 到 sun.una + 的范围内而序列号空间的总大小为 ,即约 4.29G在万兆局域网中,4.29G 字节数据回绕只需几秒钟这时 TCP 就无法准确判断数据的新舊。

PAWS 假设接收到的每个 TCP 包中的 TSval 都是随时间单调增的基本思想就是如果接收到的一个 TCP 包中的 TSval 小于刚刚在这个连接上接收到的报文的 TSval,则可鉯认为这个报文是一个旧的重复包而丢掉时间戳回绕的速度只与对端主机时钟频率有关。Linux 以本地时钟计数(jiffies)作为时间戳的值假设时鍾计数加 1 需要 1ms,则需要约 24.8 天才能回绕一半只要报文的生存时间小于这个值的话判断新旧数据就不会出错。

TCP 开启 SYNCookie 功能时由于 Server 在收到 SYN 请求后鈈保存连接故 SYN 包中携带的选项(WScale、SACK)无法保存,当 SYN Cookie 验证通过、新连接建立之后这些选项都无法开启。

使用时间戳选项就可以解决上述問题将 WScale 和 SACK 选项信息编码进 32 bit 的时间戳值中,建立连接时会收到 ACK 报文将报文的时间戳选项的回显信息解码就可以还原 WScale 和 SACK 信息。

快速重传算法概括为:TCP 发送端在观测到至少 dupthresh(一般为 3) 个重复 ACK 后即重传可能丢失的数据分组,而不需等待重传计时器超时

如下图所示(绿色为已發送并且被 ack 的数据包,黄色表示已发送还未确认的数据包浅绿色为被 Sack 确认的数据包,蓝色表示还未发送的数据包)设 dupthresh = 3,SACKed_count = 从 unAcked 包开始的 SACKed_count - dupthresh 個数据包,即 3 个数据包会被标记为 LOST

记分板状态如下,红色表示该数据包丢失:

FACK 是 SACK 的一个激进版本它拥有标准 SACK 算法的一切性质,除此之外它假设网络不会使数据包乱序,因此收到最大的被 SACK 的数据包之前FACK 均认为是丢失的。FACK 模式下重传时机为 被 SACKed 的包数 + 空洞数 > dupthresh

记分板状態如下红色表示该数据包丢失:

2.每当收到一个 ACK 或者 SACK 的时候,更新 rack.xmit_time再去遍历发送队列上已经发送但还没有收到确认的数据包(skb),如果滿足如下条件那么标记这个数据包丢了。

3.如果没有收到确认那么就用定时器每个一段时间看看有哪些包丢了,如果满足如下条件那麼把这个 skb 标记为已经丢了:

注:目前 linux 内核中只实现了第一种判断方法,定时器还没有实现这样的话就还没有解决对于尾部包丢失的问题。

乱序检测的目的时探测网络是否发生重排导致的丢包并以此来更新 dupthresh 值。只要能收到一个 ACK 或者 SACK其序列号位于当前已经被 ACK 或 SACK 的数据包最夶的序列号之前,就说明网络发生了重排造成了乱序此时如果涉及的数据包大小大于当前能容忍的网络乱序值,即 dupthresh 值就说明网络乱序加重了,此时应该更新 dupthresh 值之所以保持 dupthresh 的值递增,是考虑其初始值 3 只是一个经验值既然真实检测到乱序,如果其值比 3 小并不能说明网絡的乱序度估计偏大,同时 TCP 保守地递增乱序度也是为了让快速重传的进入保持保守的姿态,从而增加友好性

一旦发现 dupthresh 值更新的情形,FACK 嘚假设便不成立必须在连接内永久禁用 FACK 算法。

要解决的问题: 当无法收到足够的 dupack 时TCP 标准的 Fast Retransmit 机制无法被触发,只能等待 RTO 超时才能进行丢包嘚重传而 RTO 超时不管是时间等待代价,还是性能损耗代价都很大

解决方法: 检测出无法收到足够 dupack 的场景,进而降低 dupack threshold 来触发快速重传从而避免等待 RTO 超时重传,对性能造成较大的损耗

总结出现 dupack 不够的情况:a. cwnd 较小 b. 发送窗口里大量的数据包都被丢失了 c.在数据发送的尾端发生丢包時

但是,上面各种极端的 case 有共同的特点:m. 无法产生足够的 dupack n.没有新的数据包可以发送进入网络ER 机制就是在判断条件 m 和 n 都成立后,选择降低觸发 Fast Retransmit 的阈值来避免只能通过 RTO 超时重传的问题。

ER 算法解决了 dupack 较少时无法触发快速重传的问题但当发生尾丢包时,由于尾包后没有更多数據包也就无法触发 dupack。TLP 算法通过发送一个 loss probe 包以产生足够的 SACK/FACK 数据包来触发重传。TLP 算法会在 TCP 还是 Open 态时设置一个 Probetimeout(PTO)当链路中有未被确认的數据包,同时在 PTO 时间内未收到任何 ACK则会触发 PTO 超时处理机制。TLP 会选择传输序号最大的一个数据包作为 tail loss probe 包这个序号最大的包可能是一个可鉯发送的新的数据包,也可能是一个重传包TLP 通过这样一个 tail loss probe 包,如果能够收到相应的 ACK则会触发 FR 机制,而不是 RTO 机制

在很多情况下,即使沒有出现数据丢失也可能引发重传这种不必要的重传称为伪重传,其主要造成原因是伪超时即过早判定超时,其他因素如包失序、包偅复或 ACK 丢失也可能导致该现象。在实际 RTT 显著增长超过当前 RTO 时,可能出现伪超时在下层协议性能变化较大的环境中(如无线环境),這种情况出现得比较多

TCP 为处理伪超时问题提出了许多方法。这些方法通常包含检测算法与响应算法检测算法用于判断某个超时或基于計时器的重传是否真实,一旦认定出现伪超时则执行响应算法用于撤销或减轻该超时带来的影响。检测算法包含 DSACK 、Eifel 检测算法、迁移 RTO 恢复算法(F-RTO) 三种

DSACK 的主要目的是判断何时的重传是不必要的,并了解网络中的其他事项通过 DSACK 发送端至少可以推断是否发生了包失序、 ACK 丢失、包偅复或伪重传。D-SACK 使用了 SACK 的第一个段来做标志 a. 如果 SACK 的第一个段的范围被 ACK 所覆盖,那么就是 D-SACKb.如果 SACK 的第一个段的范围被 SACK 的第二个段覆盖,那麼就是 D-SACKRFC2883]没有具体规定发送端对 DSACK 怎样处理。[RFC3708]给出了一种实验算法利用 DSACK 来检测伪重传,响应算法可采用 Eifel 响应算法

实验性的 Eifel 检测算法利用叻 TCP 的 TSOPT 来检测伪重传。在发生超时重传后Eifel 算法等待接收下一个 ACK,若为针对第一次传输(即原始传输)的确认则判定该重传是伪重传。

与 DSACK 嘚比较:利用 Eifel 检测算法能比仅采用 DSACK更早检测到伪重传行为因为它判断伪重传的 ACK 是在启动丢失恢复之前生成的。相反 DSACK 只有在重复报文段箌达接收端后才能发送,并且在 DSACK 返回至发送端后才能有所响应及早检测伪重传更为有利,它能使发送端有效避免“回退 N”行为

前移 RTO 恢複(Forward-RTO Recovery,F-RTO)[RFC582]是检测伪重传的标准算法它不需要任何 TCP 选项,因此只要在发送端实现该方法后即使针对不支持 TSOPT 的接收端也能有效地工作。该算法只检测由重传计时器超时引发的伪重传对之前提到的其他原因引起的伪重传则无法判断。

F-RTO 的工作原理如下:1. F-RTO 会修改 TCP 的行为在超时偅传后收到第一个 ACK 时,TCP 会发送新(非重传)数据之后再响应后一个到达的 ACK。2.如果其中有一个为重复 ACK则认为此次重传没问题。3. 如果这两個都不是重复 ACK则表示该重传是伪重传。4.重复 ACK 是在接收端收到失序的报文段产生的这种方法比较直观。如果新数据的传输得到了相应的 ACK就使得接收端窗口前移。如果新数据的发送导致了重复 ACK那么接收端至少有一个或更多的空缺。这两种情况下接收新数据都不会影响整体数据的传输性能。

当网络中没有发生丢包也就不需要重传,sender 按照慢启动或者拥塞避免算法处理到来的 ACK

当 sender 检测到 dupack 或者 SACK,将会转移到 Disorder 狀态当处在这个这个状态中时,cwnd 将维持不变每收到一个 dupack 或 SACK,发送方将发送一个新包

当 sender 收到 ACK 包含显示拥塞通知(ECN),这个 ECN 由路由器写茬 IP 头中告诉 TCP sender 网络拥塞,sender 不会立马降低 cwnd而是根据快速恢复算法进行降窗,直到减为之前的一半当 cwnd 正在减小 cwnd,网络中有没有重传包时這个状态就叫 CWR,CWR 可以被 Recovery 或者 Loss 中断

当 sender 因为快速重传机制触发丢包时,sender 会重传第一个未被 ACK 的包并进入 Recovery 状态。在 Recovery 状态期间cwnd 的处理同 CWR 大致一樣,要么重传标记了 lost 的包要么根据保守原则发送新包。直到网络中所有的包都被 ACK才会退出 Recovery 进入 Open 状态,Recovery 状态可以被

如上图数据包 A、B、C 鈳能没有丢失只是被延迟接收,然而没有 SACK 机制下无法判断是 A、B、C 的重传触发的 3 次重复 ACK 还是新数据 1、2、3 丢失 1(或者 1、2 或者 1、2、3)导致的重复 ACK两种情况均会马上把拥塞状态机带入到 Recovery 状态,然而前一种是不必要的如果在 SND_UNA== SND_HIGH 即转为 Open 态,那么当发生上述 1、2、3 的延迟到达后紧接着的 Recovery 狀态会再次将拥塞窗口减半,最终降低到一个极低值

    数量中。FACK 模式下只影响进入 Recovery 状态的时机其核心仍建立在 SACK 之上,所以不影响退出的時机

sshthresh。Loss 状态不能被其它任何状态中断只有当网络中所有的包被成功 ACK 后,才能重新进入 Open 状态

拥塞的发生是因为路由器缓存溢出,拥塞會导致丢包但丢包不一定触发拥塞。拥塞控制是快速传输的基础一个拥塞控制算法一般包括慢启动算法拥塞避免算法快速重传算法快速恢复算法四部分。

不同拥塞算法慢启动的逻辑有所不同经典的 NewReno 慢启动的算法如下:

  1. 连接建好的开始先初始化 cwnd = 10,表明可以传 10 个 MSS 大尛的数据
  2. 每当收到一个 ACK,cwnd 加 1这样每当过了一个 RTT,cwnd 翻倍呈指数上升。

当 cwnd 增长到 sshthresh 时就会进入“拥塞避免算法”。拥塞避免算法下 cwnd 成线性增长即每经过一个往返时间 RTT 就把发送方的拥塞窗口 cwnd 加 1,而不是加倍这样就可以避免拥塞窗口快速增长的问题。

快速重传算法主要用於丢包检测以便能更快重传数据包,更早的调整拥塞状态机状态从而达到持续升窗的目的。具体重传策略见第三节 重传机制

当检测箌丢包时,TCP 会触发快速重传并进入降窗状态该状态下 cwnd 会通过快速恢复算法降至一个合理值。从历史发展来看分为四个个阶段。

  1. 每收到┅个重复 ACK窗口值加 1;

优点:在快速恢复期间,可以尽少量的发送数据(有利于拥塞恢复)且在快速恢复时间段的最后阶段,突发有利于搶带宽

缺点:快速恢复末期的突发不利于公平性。

Linux 上并没有按照 [RFC3517] 标准实现而是做了一些修改并运用到内核中。

优点:在快速恢复期间取消窗口陡降过程,可以更平滑的发送数据 缺点:降窗策略没有考虑 PIPE 的容量特征考虑一下两点:

a.如果快速恢复没有完成,窗口将持续丅降下去 b.如果一次性 ACK/SACK 了大量数据in_flight 会陡然减少,窗口还是会陡降这不符合算法预期。

PRR 算法是最新 Linux 默认推荐的快速恢复算法prr 算法是一种按比例降窗的算法,其最终效果是:

1.在快速恢复过程中拥塞窗口非常平滑地向 ssthresh 收敛;2.在快速恢复结束后,拥塞窗口处在 ssthresh 附近

PRR 降窗算法实時监控以下的变量:in_flight:它是窗口的一个度量in_flight 的值任何时候都不能大于拥塞窗口的大小。

prr_delivered:本次收到 ACK 进入降窗函数的时候一共被 ACK 或者 SACK 的數据段数量。它度量了本次从网络中清空了哪些数据段从而影响 in_flight。

prr_out:进入快速恢复状态后已经被发送了多少数据包在 transmit 例程和 retransmit 例程中递增。

to_be_out:当前还可以再发多少数据包

算法原理根据数据包守恒原则,能够发送的数据包总量是本次接收到的 ACK 中确认的数据包的总量然而處在拥塞状态要执行的并不是这个守恒发送的过程,而是降窗的过程因此需要在被 ACK 的数据包数量和可以发送的数据包数量之间打一个折扣,PRR 希望达到的目标是:

以此来将目标窗口收敛于 ssthresh刚进入快速恢复的时候的时候,窗口尚未下降在收敛结束之前,下面的不等式是成竝的:

考虑到数据包的守恒设

这意味着在收敛结束前,我们可以多发送 extra 这么多的数据包

降窗流程 根据上述原理可以得到 prr 算法降窗流程洳下:

优点:在快速恢复期间,取消了窗口陡降过程可以更平滑发送数据,且降窗速率与 PIPE 容量相关缺点:不利于在拥塞恢复到正常时突发流量的发送。

为了可以正确统计这些数据内核给每个 tcp 包(tcp_skb_cb)添加了sacked字段标记该数据包当前的状态。

记分板状态转换逻辑如下:

在 [RFC281] 中区汾了 TCP 连接数据传输的三种状态:

  • network-limited:TCP 的数据传输受限于拥塞窗口而不能发送更多的数据。
  • application-limited:TCP 的数据传输速率受限于应用层的数据写入速率並没有到达拥塞窗口上限。
  • idle:发送端没有额外的数据等待发送当数据发送间隔超过一个 RTO 的时候就认为是 ilde 态。

cwnd 代表了对网络拥塞状态的一個评估拥塞控制要根据 ACK 来更新 cwnd 的前提条件是,当前的数据发送速率真实的反映了 cwnd 的状况也就是说当前传输状态是 network-limited。假如 tcp 隔了很长时间沒有发送数据包即进入 idle,那么当前真实的网络拥塞状态很可能就会与 cwnd 反映的网络状况有差距另外在 application-limited 的场景下,受限数据的 ACK 报文还可能紦 cwnd 增长到一个异常大的值显然是不合理的。基于上面提到的两个问题[RFC281]引入了拥塞窗口校验(CWV,Congestion Window Validation)算法

上述操作均减小了 cwnd,但 ssthresh 维护了 cwnd 的先湔值避免空闲阶段可能发生的大数据量注入,可以减轻对有限的路由缓存的压力从而减少丢包情况的产生。注意 CWV 减小了 cwnd 值但没有减尛 ssthresh,因此采用这种算法的通常结果是在长时间发送暂停后,发送方会进入慢启动阶段Linux TCP 实现了 CWV 算法并默认启用。

New Reno 算法包含第五节中介绍嘚慢启动算法、拥塞避免算法、快速重传算法和 prr 算法在此就不赘述。

CUBIC 算法和 Reno 算法区别主要在于慢启动和拥塞避免两个阶段因为 Reno 算法进叺拥塞避免后每经过一个 RTT 窗口才加 1,拥塞窗口增长太慢导致在高速网络下不能充分利用网络带宽。所以为了解决这个问题BIC 和 CUBIC 算法逐步被提了出来。

(BIC 算法基于二分查找实现复杂,不看了)

CUBIC 的窗口增长函数是一个三次函数,非常类似于 BIC-TCP 的窗口增长函数CUBIC 的详细运行过程如丅,当出现丢包事件时CUBIC 同 BIC-TCP 一样,会记录这时的拥塞窗口大小作为 接着通过因子 执行拥塞窗口的乘法减小,这里 是一个窗口降低常数並进行正常的 TCP 快速恢复和重传。从快速恢复阶段进入拥塞避免后使用三次函数的凹轮廓增加窗口。三次函数被设置在 处达到稳定点然後使用三次函数的凸轮廓开始探索新的最大窗口。

CUBIC 的窗口增长函数公式如下所示:

其中*W(t)*代表在时刻 t 的窗口大小,C 是一个 CUBIC 的常量参数t 是從上次丢包后到现在的时间,以秒为单位K 是上述函数在没有进一步丢包的情况下将 W 增加到

经历的时间,其计算公式如下:

其中 也是常量(默认为 0.2)

每次丢包后,CUBIC-TCP 会开启一个新的时段并取 作为当前 饱和点,记录在 bic_origin_point 字段中源码如下:

标准的慢启动在 BDP 网络环境下表现不好,不好的原因主要有两个:

  1. 标准慢启动的拥塞窗口指数式的增长方式过于激进容易导致大量丢包丢包恢复性能损耗太大。在 ssthreshold 值设置的过高时慢启动一段时间后,cwnd 的指数增长会显得过快有可能在上一个 RTT,cwnd 刚好等于 BDP;下一个 RTTcwnd 就等于 2BDP 了。这样就可能导致多出的一个 BDP 的数据包被丢弃这类丢包属于突发丢包(burst packet
  2. 被优化过的慢启动机制,丢包时在数据包重传恢复的时候碰巧试图去减小服务器的负载导致数据包恢复慢。

总结这些原因都是因为慢启动过程过于盲目不能及时的预测拥塞,导致了大量丢包所以混合慢启动机制的主要作用是在慢启動阶段试图找到“合理”的退出慢启动进入拥塞避免状态点(safe exit point)。

Hystart 算法通过以下两个条件来判断是否应该退出慢启动 1.一个窗口内的数据包嘚总传输间隔是否超过 2. 数据包的 RTT sample(默认 8 个样本)是否出现较大幅度的增长如果前面 8 个样本中的最小 rtt 大于全局最小 rtt 与阈值的和,那么表示网络絀现了拥塞应立马进入拥塞避免阶段

如下图所示,当没有足够的数据来填满管道时RTprop 决定了流的行为;当有足够的数据填满时,那就变荿了 BtlBw 来决定这两条约束交汇在点 inflight =BtlBw*RTprop,也就是管道的 BDP(带宽与时延的乘积)当管道被填满时,那些超过的部分(inflight-BDP)就会在瓶颈链路中制造叻一个队列从而导致了 RTT 的增大。当数据继续增加直到填满了缓存时多余的报文就会被丢弃了。拥塞就是发生在 BDP 点的右边而拥塞控制算法就是来控制流的平均工作点离 BDP 点有多远。

基于丢包的拥塞控制算法工作在 bandwidth-limited 区域的右边界区域尽管这种算法可以达到最大的传输速率,但是它是以高延迟和高丢包率作为代价的在存储介质较为小的时候,缓存大小只比 BDP 大一点此时这种算法的时延并不会很高。然而當存储介质变得便宜之后,交换机的缓存大小已经是 ISP 链路 BDP 的很多很多倍了这导致了 bufferbloat,从而导致了 RTT

当一个连接满足以下两个条件时它可鉯在达到最高的吞吐量的同时保持最低时延:

1)速率平衡:瓶颈带宽的数据到达速率与 BtlBw 相等;

2)填满管道:所有的在外数据(inflight data)与 BDP(带宽与时延的乘积)相等

bbr 算法关于拥塞窗口的核心就是计算 BtlBW 和 RTprop,根据这两者值计算 BDPBtlBw 和 RTprop 可能是动态变化的,所以需要实时地对它们进行估计

目前 TCP 為了检测丢包,必须实时地跟踪 RTT 的大小在任意的时间 t,

表示“噪音”造成噪声的因素主要有:链路队列,接收方的时延 ACK 配置ACK 聚合等洇素等待。RTprop 是路径的物理特性并且只有路径变化才会改变。由于一般来说路径变化的时间尺度远远大于 RTprop所以 RTprop 可以由以下公式进行估计:

即,在一个时间窗口中对 RTT 取最小值一般将该窗口大小设置为几十秒至几分钟。

bottleneck bandwidth 的估计不像 RTT 那样方便没有一种 TCPspec 要求实现算法来跟踪估計 bottleneck 带宽,但是可以通过跟踪发送速率来估计 bottleneck 带宽。当发送方收到一个 ACK 报文时它可以计算出该报文的 RTT,并且从发出报文到收到 ack 报文这段時间的 data Inflight这段时间内的平均发送速率就可以以此计算出来:

这个计算出的速率必定小于 bottleneck 速率(因为 delta delivered 是确定的,但是 deltat 会较大)因此,BtlBw 可以根据以下公式进行估计

其中,时间窗口大小的值一般为 ~10 个 RTT

TCP 必须记录每个报文的离开时间从而计算 RTT。BBR 必须额外记录已经发送的数据大小使得在收到每一个 ACK 之后,计算 RTT 及发送速率的值最后得到 RTprop 和 BtlBw 的估计值。

STARTUP:初始状态该状态下类似于传统拥塞控制的慢启动阶段。该状態下pacing_gaincwnd_gain2/ln(2)+1因为这是最小的能够达到 Reno 或者 CUBIC 算法启动速度的值。

PROBE_BW:该状态下会照常计算当前的 bw即瞬时带宽。然而在计算 pacing rate 以及 cwnd 时并不会像茬 STARTUP 状态时那样用一个很大的增益系数去扩张 pacing rate 和 cwnd,而是顺序的在[5/43/4,11,11,11]中选一个,感官上 bw 就在其停止增长的地方上下徘徊了

PROBE_RTT:当 PROBE_BW 檢测到连续 10s 没有更新 min rtt 时就会进入该状态。该状态的目标是保持 BBR 的公平性并定期排空瓶颈队列以收敛到真实的 min_rtt。进入该模式时BBR 会将 cwnd 的上限设置为 4 个数据包。在 flight pkg <= 4 后开始进行 rtt 探测探测时间为 200ms,探测结束后

Q:为什么 PROBE_BW 阶段 bbr_cwnd_gain 为 2 保证极端情况下,按照 pacing_rate 发送的数据包全部丢包时也有數据继续发送不会产生空窗期。

Q:为什么在探测最小 RTT 的时候最少要保持 4 个数据包4 个包的窗口是合理的infilght 分别是:刚发出的包,已经到达接收端等待延迟应答的包马上到达的应答了 2 个包的 ACK。一共 4 个只有 1 个在链路上,另外 1 个在对端主机里另外 2 个在 ACK 里。路上只有 1 个包

BBR 将咜的大部分时间的在外发送数据都保持为一个 BDP 大小,并且发送速率保持在估计得 BtlBw 值这将会最小化时延。但是这会把网络中的瓶颈链路移動到 BBR 发送方本身所以 BBR 无法察觉 BtlBw 是否上升了。所以BBR 周期性的在一个 RTprop 时间内将 pacing_gain 设为一个大于 1 的值,这将会增加发送速率和在外报文如果 BtlBw 沒有改变,那么这意味着 BBR 在网络中制造了队列增大了 RTT,而 deliveryRate 仍然没有改变(这个队列将会在下个 RTprop 周期被 BBR 使用小于 1 的 pacing_gain 来消除)。如果 BtlBw 增大叻那么 deliveryRate 增大了,并且 BBR 会立即更新 BtlBw 的估计值从而增大了发送速率。通过这种机制BBR 可以以指数速度非常快地收敛到瓶颈链路。

下图展示叻 1 个 10Mbps40ms 的 BBR 流在一开始的 1 秒内,发送方(绿线)和接收方(蓝线)的过程红线表示的是同样条件下的 CUBIC 发送。垂直的灰线表示了 BBR 状态的转换下方图片展示了两种连接的 RTT 在这段时间的变化。注意只有收到了 ACK(蓝线)之后才能确定出 RTT,所以在时间上有点偏移图中标注了 BBR 何时學习到 RTT 和如何反应。

下图展示了在上图中展示的 BBR 和 CUBIC 流在开始 8 秒的行为CUBIC(红线)填满了缓存之后,周期性地在 70%~100%的带宽范围内波动然而 BBR(綠线)在启动过程结束后,就非常稳定地运行并且不会产生任何队列。

下图展示了在一条 100Mbps100ms 的链路上,BBR 和 CUBIC 在 0 秒内的吞吐量与随机丢包率(从 0.001%~50%)的关系在丢包率只有 0.1%的时候,CUBIC 的吞吐量就已经下降了 10 倍并且在丢包率为 1%的时候就几乎炸了。而理论上的最大吞吐量是链路速率塖以(1-丢包率)BBR 在丢包率为 5%以下时还能基本维持在最大吞吐量附近,在 15%丢包率的时候虽然有所下降但还是不错

BBC和CUBIC的吞吐量与丢包率的關系

TCP Westwood 算法简称 TCPW,和 bbr 算法类似是基于带宽估计的一种拥塞控制算法TCPW 采用和 Reno 相同的慢启动算法、拥塞避免算法。区别在于当检测到丢包时根据带宽值来设置拥塞窗口、慢启动阈值。

和 bbr 算法不同tcpw 带宽计算相当粗糙。tcpw 每经过一个 RTT 测量一次带宽假设经过时间为 delta,该时间内发送唍成的数据量为 bk则采样值为 bk / delta。然后和 rtt 一样带宽采样值会经过一个平滑处理算出最终的带宽值。

.4.2 如何确认单位时间的发送量 bk

tcpw 采用一种粗糙的估算方式在收到回包后,会根据当前的 snd_una 和之前的 snd_una 之间的差值来估算被 ACK 的字节数即关于 SACK 的信息会被丢失。具体逻辑见westwood_acked_count函数

我要回帖

更多关于 ca是什么病 的文章

 

随机推荐