作为TCP的重头戏,本章节涉及了许多关于计算方面的内容,使用了大量的例子来指明一些观点。

我使用的理解方法是:通过别人的博客,以及实例结合进行理解,不然会很吃力。

21.1 引言 reliable

TCP提供可靠的运输层,它使用的方法之一就是确认从另外一端收到的数据。

也就是说通过ACK,或者说 TCP自时钟,来保证这一特性。

TCP通过在发送的时候,设置一个定时器来解决这些问题。如果当定时器溢出还没有收到确认,就重传数据,对于任何的实现而言,关键就在超时和重传的策略。

四个不同的定时器

重传定时器:使用于 当希望收到另外一端的确认。 -与本章有关

坚持定时器:使窗口信息不断流动。

保活(keep-alive)定时器:检测一个空闲的连接的另外一端何时崩溃或重启。

2MSL定时器:用于测量一个连接处于 TIME_WAIT 状态的时间。

我的小概况

首先介绍的是,RTT和RTO的计算,当成功接收到确认的时候,使用公式法,当没有接收到而超时的时候,采用指数避退法。

然后接入慢启动和拥塞逼退算法,也就是 避免网络拥塞 TCP所采取的算法。还有旁带介绍了快速启动和快速恢复算法。

抓住两个关键的英文单词:ssthresh慢启动门限,cwnd拥塞窗口。

最后一笔带过了 之前提及的路由度量 还有 TCP如何处理ICMP差错,以及重新分组的内容。前面的两块内容相比之下更需要理解 和掌握。

第一部分:超时

21.2 & 21.3 RTT 和 RTO 的内容

当没有接收到ACK的时候的策略:指数退避

当发送方没有收到 由接收方对数据的 ACK 的时候,RTO 使用的是 指数退避策略:重传时间RTO 在重传定时器每一次的超时溢出之后 都翻一倍,直到64s。

记住这个前提,如果是接收到了ACK的话,有可能会对RTO进行更新(超时并重传一次之后 接收到的话有可能会造成二义性,所以不进行更新),那么使用的是公式更新RTO的方法。

当接收到ACK的时候(正常情况)的策略:公式法(均值和方差法) RTT估计器

TCP超时与重传中 最重要的部分 就是 对一个给定连接的往返时间(RTT)的测量。这个时间会经常发生变化,所以TCP必须对它进行跟踪。

首先 TCP 必须测量在发生一个 带有特别序号 的字节 和 接收包含该字节的确认 之间的RTT。

最初的公式

最初的TCP规范 使TCP使用 低通过滤器 来更新一个 被平滑的RTT估计器(记为R)

R <- aR + (1-a)M 这里的 a 为一个推荐值为0.9的 平滑因子。M是新测量的RTT。

RTO = Rβ β 是一个推荐值为2的 时延离散因子。

也就是说,这个公式 是根据一个估计器(R) 来计算 RTO 的。估计器的90% 来自前面的估计器,10%来自新测量的RTT。

新的公式(Jacobson) 均值偏差 -减小误差

在RTT变化很快的情况之下,以前旧的公式无法跟上这种变化,会引起不必要的重传。

新的公式根据两个东西来计算:(1)RTT估计器 (2)均值与偏差(D) 最大程度的减小了误差。

在往返时间变化起伏很快的情况之下,基于 均值和方差 来计算RTO,能够提供更好的相应。

Err <- M(测量的RTT) - A(之前的RTT估计器)
A <- A + g(1/8 即 0.125) * Err
D <- D + h(偏差的增益 取0.25) * [|Err| - D]
RTO = A + 4D

相关的内容参见教材P228。

按我自己的理解 这些新加入的 比如偏差的增益 平均的g 都是为了尽可能地减小RTO的误差。

均值偏差 是对标准偏差的一种好的逼近,但却更容易进行计算。

顺便一提的是,g,h 和倍数4 都是2的倍数,这也是Jacobson的设计:计算均可通过 移位操作

Karn算法 -解决重传二义性问题

当一个分组发送之后发生了超时,RTO根据之前的 指数退避 增长,分组以更长的RTO进行重传。然后收到了一个ACK。

那么这个ACK是针对第一个分组(超时的)的 还是针对第二个分组的(重传的)?

Karn 规定,当一个重传和超时发送的时候,在重传数据的确认最后到达的时候,不能更新RTT估计器,因为我们不知道ACK对应哪个数据报:是之前超时的呢?还是重传的呢?

此时RTO已经因为超时而得到了更新,下次传输的时候使用这个更新的RTO。

21.4 往返时间RTT的例子

并不是所有发送的数据报都被计时:在发送一个报文段的时候,如果给定连接的定时器已经被使用,则该报文段不被计时。

每次调用 500msTCP定时器例程 的时候,都会增加一个计数器来完成计时。

根据教材中的例子和我个人的理解,这个计时器(或者说时钟滴答),是在特定的时间计数的。比如 我在 0s 发送了一个数据报,在 1.061s 接收到了这个数据报的ACK,那么由于在这个过程中,计数器分别在 0.03s,0.53s,1.03s 进行了时钟滴答(第一个滴答一定在 0-0.061s 之间),所以一共是 三个时钟滴答。

在随后的RTO计算的时候,这个计数器得到的时钟滴答,用于计算往返时间:也就是上面新公式的M。

相关计算 参照教材 P232. 需要说明的一点是,初始化的时候:RTT估计器 A = 0,偏差的增益 D = 3s,RTO = A + 2D。

第二部分:重传

重头戏:TCP应对网络拥塞的策略

Review

流量控制:发送方-cwnd拥塞窗口 接收方-rwnd通告窗口

本章节主要和 cwnd 有关。

防止网络拥塞:慢启动 ssthresh 拥塞避免算法

本章主要介绍 TCP如何实现流量控制和避免网络拥塞

21.5 & 21.6 慢启动 与 拥塞避免算法

这一部分的知识点,可以参考:TCP慢启动、拥塞避免、快速重传、快速回复 归纳的非常详细,通俗易懂。

简单的来说,慢启动 和 拥塞避免算法 实现的内容基本都差不多,只不过 慢启动 是接收到一个ACK 就让 cwnd +1,而 拥塞避免 是接收到发送的所有数据报的 ACK 才让 cwnd +1。

慢启动 一点也不慢,它对 拥塞窗口cwnd 采用的是指数型增长,而 拥塞避免 是为了防止 慢启动后期 cwnd增长的速度过快,把这个速度控制下来,避免造成拥塞。拥塞避免 采取的是 加法增长。

区别 慢启动 和 拥塞避免 的界限是 ssthresh慢启动门限,当 cwnd(计数单位为数据段) 的值 x MSS = 总的字节数 > ssthresh(一般为65535字节) 的时候,停止慢启动,启动 拥塞避免。当前者小于后者的时候 也就是开始阶段 使用的是 慢启动。

慢启动 和 拥塞避免 算法 假定:当分组丢失的时候,意味着 在源主机和目的主机之间的网络 发送了拥塞。(由于分组受到损害而引起的丢失 是非常少的(<<1%))

当拥塞发生的时候,我们希望降低分组进入网络的传输速率,所以我们采用了慢启动,在实际中 慢启动 和 拥塞避免 一般在一起实现。

算法概要 -教材P235:

1.对一个给定的连接,初始化cwnd为1个报文段,ssthresh为65535个字节。

2.TCP输出例程的输出不能超过cwnd和接收方通告窗口的大小。拥塞避免是发送方使用 的流量控制,而通告窗口则是接收方进行的流量控制。前者是发送方感受到的网络拥塞的估计,而后者则与接收方在该连接上的可用缓存大小有关。

3.当拥塞发生时(超时或收到重复确认),ssthresh被设置为当前窗口大小的一半(cwnd 和接收方通告窗口大小的最小值,但最少为2个报文段)。此外,如果是超时引起了拥塞,则 cwnd被设置为1个报文段(这就是慢启动)。

4.当新的数据被对方确认时,就增加cwnd,但增加的方法依赖于我们是否正在进行慢启动或拥塞避免。如果cwnd小于或等于ssthresh,则正在进行慢启动,否则正在进行拥塞避免。 慢启动一直持续到我们回到当拥塞发生时所处位置的半时候才停止(因为我们记录了在步骤2 中给我们制造麻烦的窗口大小的一半),然后转为执行拥塞避免。

21.7 快速重传 和 快速恢复

当TCP连续收到三个重复的ACK的时候,就假定一个报文段已经丢失并且重传自那个序号起的一个报文段。这就是快速重传算法。

如果接下来执行的不是 慢启动算法 而是 拥塞避免算法,这就是快速恢复算法。没有执行慢启动的原因:收到重复的ACK不仅仅告诉我们一个分组丢失了,由于接收方只有在收到一个报文段的时候才会返回ACK,所以 在收发两端之间 还有流动的数据,我们不希望执行慢启动来突然减少数据流。

算法概要P237:

1.当收到第3个重复的ACK时,将ssthresh设置为当前拥塞窗口cwnd的一半。重传丢失的 报文段。设置cwnd为ssthresh加上3倍的报文段大小。

2.每次收到另一个重复的ACK时, cwnd增加1个报文段大小并发送1个分组(如果新的 cwnd允许发送)。

3.当下一个确认新数据的ACK到达时,设置cwnd为ssthresh(在第1步中设置的值)。这个 ACK应该是在进行重传后的一个往返时间内对步骤1中重传的确认。另外,这个ACK也应该 是对丢失的分组和收到的第1个重复的ACK之间的所有中间报文段的确认。这一步采用的是拥 塞避免,因为当分组丢失时我们将当前的速率减半。

最终,拥塞窗口将会超过接收方的通告窗口rwnd,意味着通告窗口将对数据流进行限制。

第三部分:其他内容

21.9 按每条路由进行度量

在介绍IP协议的时候,介绍了度量这个概念,当时是以跳数作为度量。

现在可以将 TCP的超时与重传 的相关信息保存在路由表项中:

  • 被平滑的 RTT 估计器
  • 被平滑的 均值偏差
  • ssthresh慢启动门限
  • MT
  • 输出的带宽时延乘积
  • 输入的带宽时延乘积

21.10 ICMP的差错 如何处理

一个接受到的 源站抑制ICMP差错:拥塞窗口cwnd 设置为1,启动 慢启动,ssthresh不变。

接受到的 主机不可达 或者 网络不可达:被忽略。因为这些都被认为是短暂现象,有可能是中间路由关闭了。TCP试图发送引起该差错的数据,尽管有可能超时。

21.11 重新分组

当TCP超时且重传的时候,它不一定要重传相同的报文段,相反 TCP允许重新分组而发送一个较大的报文段,有助于提高性能。因为 TCP是使用字节序号,而不是使用报文段序号 来识别发送的数据 和进行确认。

2016/8/18

【TCP/IP详解 卷一:协议】第二十一章 TCP的超时与重传的更多相关文章

  1. TCP/IP详解 卷1 第二十一章 TCP的超时与重传

    21.1 引言 可靠性的保证之一就是超时重传 前面两个超时重传的例子 1)  ICMP端口不能到达时,TFTP客户使用UDP实现了一个简单的超时和重传机制,假定5s是一个适当是时间间隔,并每隔5s进行 ...

  2. TCP/IP详解 卷一(第十一章 UDP:用户数据报协议)

    UDP是一个简单的面向数据报的运输层协议. UDP不提供可靠性:它把应用程序传给IP层的数据发送出去,但是并不保证它们能到达目的地. UDP首部的个字段如下图所示

  3. TCP/IP详解 卷一(第十七章 TCP:传输控制协议)

    与UDP协议相比,TCP提供一种面向连接的.可靠的字节流服务. TCP首部 跟UDP一样,TCP数据被封装在一个IP数据报中,下面显示TCP的首部数据格式 每个TCP段都包含源端和目的端的端口号,用于 ...

  4. TCP/IP详解 卷一(第二章 链路层)

    在TCP/IP协议族中,链路层主要有三个目的: 1.为IP模块发送和接收IP数据报 2.为ARP模块发送ARP请求和接收ARP应答 3.为RARP请求和接收RARP应答 TCP/IP支持多种不同的链路 ...

  5. TCP/IP详解 卷一(第三章 IP:网际协议)

    IP是TCP/IP协议族中最为核心的协议.所有的TCP.UDP.ICMP及IGMP数据都以IP数据报格式传输. IP提供不可靠.无连接的数据报传送服务. 1.不可靠:就是它不能保证IP数据报能成功地到 ...

  6. TCP/IP详解 卷1 第十七章 TCP:传输控制协议

    17.2 TCP的服务 TCP提供了一种面向连接的.可靠的字节流服务.两个使用TCP的应用在彼此交换数据之前必须先建立一个TCP连接. TCP通过下列方式来提供可靠性: 1)  应用数据被分割成TCP ...

  7. TCP/IP详解 卷一(第二十章 TCP的成块数据流)

    本章将介绍TCP所使用的被称为滑动窗口协议的一种流量控制方法. 该协议允许发送方在停止并等待确认前可以连续发送多个分组,这样就可以加速数据的传输. 滑动窗口 下图用可视化的方法显示了滑动窗口协议 我们 ...

  8. TCP/IP详解 卷一(第十三章 IGMP:Internet组管理协议)

    本章将介绍用于支持主机和路由器进行多播的Internet组管理协议(IGMP) 它让一个物理网络上的所有系统知道主机当前所在的多播组.多播路由器需要这些信息以便知道多播数据报应该向那些接口转发. 跟I ...

  9. TCP/IP详解 卷一(第六章 ICMP:Internet控制报文协议)

    ICMP是(Internet Control Message Protocol)Internet控制报文协议. 用于在IP主机.路由器之间传递控制消息.控制消息是指网络通不通.主机是否可达.路由是否可 ...

  10. TCP/IP详解 卷一(第十八章 TCP连接的建立和终止)

    建立连接 建立一个TCP连接时会发生下述情况 1.客户TCP发送一个SYN(同步)分节,它告诉服务器将在(待建立)连接中发送的数据的初始序列号. 2.服务器确认(ACK)客户的SYN,同时自己也得发送 ...

随机推荐

  1. (转)FastDFS文件存储

    一.FastDFS介绍 FastDFS开源地址:https://github.com/happyfish100 参考:分布式文件系统FastDFS设计原理 参考:FastDFS分布式文件系统 个人封装 ...

  2. IE加载项

    加载项   加载项也称为ActiveX控件.浏览器扩展.浏览器帮助应用程序对象或工具栏,可以通过提供多媒体或交互式内容(如动画)来增强对网站的体验. 但是,某些加载项可导致计算机停止响应或显示不需要的 ...

  3. Weka——PrincipalComponents分析

    package weka.filters.unsupervised.attribute; PrincipalComponents 属性: /** The data to transform analy ...

  4. [LeetCode] 256. Paint House_Easy tag: Dynamic Programming

    There are a row of n houses, each house can be painted with one of the three colors: red, blue or gr ...

  5. 使用TreeView加载XML文件

    PS: 由于小弟初学编程,本文只写实现方式,代码写的不是很好请见谅! 1.需要读取的xml文档内容 2. 最终实现效果 3  貌似看起实现起来很复杂 但是想想还是挺简单 思路:  读取XML文档 →获 ...

  6. memcache分布式布置方案

    利用hash算法 key->hash->取余%2 mod ->server=array()=>server[mod]算出是第几个memcache服务器

  7. mysql日志详解

    日志分类: 一.错误日志. 1.在配置文件中的配置是:log-error="DESKTOP-igoodful.err",查看参数的键值对:show variables like ' ...

  8. DOM EVENT

    属性 此事件发生在何时... onabort 图像的加载被中断. onblur 元素失去焦点. onchange 域的内容被改变. onclick 当用户点击某个对象时调用的事件句柄. ondblcl ...

  9. Linux命令: 编辑模式移动光标

    敲命令按以下顺序 ①vim filename ②e ③i ④ESC 移动光标 0 (零):将光标移动到行的起始处. $:将光标移动到行的末尾处. H:将光标移到当前窗口(而非全文)的第一行起始处. M ...

  10. nginx日志过滤相同IP方法

    nginx日志过滤相同IP方法分析nginx日志的时候,统计ip怎么过滤重复的?awk '{print $2}' nginx.log |sort -rn |uniq -c |sort -rn |hea ...