【TCP/IP详解 卷一:协议】第二十一章 TCP的超时与重传
作为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的超时与重传的更多相关文章
- TCP/IP详解 卷1 第二十一章 TCP的超时与重传
21.1 引言 可靠性的保证之一就是超时重传 前面两个超时重传的例子 1) ICMP端口不能到达时,TFTP客户使用UDP实现了一个简单的超时和重传机制,假定5s是一个适当是时间间隔,并每隔5s进行 ...
- TCP/IP详解 卷一(第十一章 UDP:用户数据报协议)
UDP是一个简单的面向数据报的运输层协议. UDP不提供可靠性:它把应用程序传给IP层的数据发送出去,但是并不保证它们能到达目的地. UDP首部的个字段如下图所示
- TCP/IP详解 卷一(第十七章 TCP:传输控制协议)
与UDP协议相比,TCP提供一种面向连接的.可靠的字节流服务. TCP首部 跟UDP一样,TCP数据被封装在一个IP数据报中,下面显示TCP的首部数据格式 每个TCP段都包含源端和目的端的端口号,用于 ...
- TCP/IP详解 卷一(第二章 链路层)
在TCP/IP协议族中,链路层主要有三个目的: 1.为IP模块发送和接收IP数据报 2.为ARP模块发送ARP请求和接收ARP应答 3.为RARP请求和接收RARP应答 TCP/IP支持多种不同的链路 ...
- TCP/IP详解 卷一(第三章 IP:网际协议)
IP是TCP/IP协议族中最为核心的协议.所有的TCP.UDP.ICMP及IGMP数据都以IP数据报格式传输. IP提供不可靠.无连接的数据报传送服务. 1.不可靠:就是它不能保证IP数据报能成功地到 ...
- TCP/IP详解 卷1 第十七章 TCP:传输控制协议
17.2 TCP的服务 TCP提供了一种面向连接的.可靠的字节流服务.两个使用TCP的应用在彼此交换数据之前必须先建立一个TCP连接. TCP通过下列方式来提供可靠性: 1) 应用数据被分割成TCP ...
- TCP/IP详解 卷一(第二十章 TCP的成块数据流)
本章将介绍TCP所使用的被称为滑动窗口协议的一种流量控制方法. 该协议允许发送方在停止并等待确认前可以连续发送多个分组,这样就可以加速数据的传输. 滑动窗口 下图用可视化的方法显示了滑动窗口协议 我们 ...
- TCP/IP详解 卷一(第十三章 IGMP:Internet组管理协议)
本章将介绍用于支持主机和路由器进行多播的Internet组管理协议(IGMP) 它让一个物理网络上的所有系统知道主机当前所在的多播组.多播路由器需要这些信息以便知道多播数据报应该向那些接口转发. 跟I ...
- TCP/IP详解 卷一(第六章 ICMP:Internet控制报文协议)
ICMP是(Internet Control Message Protocol)Internet控制报文协议. 用于在IP主机.路由器之间传递控制消息.控制消息是指网络通不通.主机是否可达.路由是否可 ...
- TCP/IP详解 卷一(第十八章 TCP连接的建立和终止)
建立连接 建立一个TCP连接时会发生下述情况 1.客户TCP发送一个SYN(同步)分节,它告诉服务器将在(待建立)连接中发送的数据的初始序列号. 2.服务器确认(ACK)客户的SYN,同时自己也得发送 ...
随机推荐
- Linux输入输出重定向和文件查找值grep命令
Linux输入输出重定向和文件查找值grep命令 一.文件描述符Linux 的shell命令,可以通过文件描述符来引用一些文件,通常使用到的文件描述符为0,1,2.Linux系统实际上有12个文件描述 ...
- 简述ASP.NET的页面运行机制
在深入学习ASP.NET之前,首先需要先了解一下ASP.NET的页面运行机制: 浏览以下内容需要对ASP.NET管道有一定的了解,附上很不错的几个链接: 选择HttpHandler还是HttpModu ...
- java的redis工具类
package com.mracale.sell.utils; /** * @Auther: Mracale */ import org.springframework.beans.factory.a ...
- [LeetCode] 721. Accounts Merge_Medium tag: DFS recursive
Given a list accounts, each element accounts[i] is a list of strings, where the first element accoun ...
- 去掉python的警告
1.常规警告 import warnings warnings.filterwarnings("ignore") 2.安装gensim,在python中导入的时候出现一个警告: w ...
- LeetCode--53 最大连续子序列(总结)
# 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. # 示例:# 输入: [-2,1,-3,4,-1,2,1,-5,4],# 输出: 6# 解释 ...
- C语言typeof详解
前言: typeof关键字是C语言中的一个新扩展,这个特性在linux内核中应用非常广泛. 一,说明 typeof的参数可以是两种形式:表达式或类型. 1,表达式的的例子: ...
- Summary: rand5构造rand7
给一个方法,比如 rand5(), 它能够等概率生成 1-5 之间的整数. 所谓等概率就是1,2,3,4,5 生产的概率均为 0.2 .现在利用rand5(), 构造一个能够等概率生成 1- 7 的方 ...
- excel输入数字变成特殊符号问题
问题,在单元格里输入数字,结果变成文件夹类型的小图片或特殊符号了,原因是字体为Wingdings,将其设为Times New Roman即可
- linux常用命令:ps 命令
Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信 ...