一:确认应答和序列号

在tcp中,发送端的数据到达主机时,接收端会返回一个已收到的通知。这个消息叫做确认应答(ACK)。

当发送端发送数据后,会等待对端的确认应答。如果有确认应答,说明数据已经成功到达。反之,则数据丢失的可能性很大。

发送端一定时间内没有等到确认应答,发送端就认为数据已经丢失了,就可以重发数据。因此,即使产生了丢包,也能保证数据到达对端。实现可靠传输。

想一下:为什么发送端一定时间内没有收到确认应答呢?有哪些原因呢?

这里有几个对象:

1、发送端,发送的数据

2、对端,回应的ACK数据

3、中间的网络

第一种 发送端:发送端的数据根本没有到达对端,发送的数据在途中就已经丢失了。

第二种 对端:可能数据对方已经收到了,只是回应ACK的数据时,途中丢失了。这种情况会导致发送端没有收到对端的确认应答。

第三种:网络:由于网络拥堵,确认应答ACK延迟到达了。或者发送端的数据延迟到达对端了。这种情况也可能导致重发数据包。

上面这些情况都有可能导致发送端没有收到对端的ACK应答。

上面说了, 如果需要发送端重发数据,那需要重发哪部分数据,发送端怎么知道重发哪部分数据?

这个就是序列号功能了。

什么是序列号:

序列号是按照顺序给发送数据的每一个字节都编号。

接收端接收数据TCP首部中的序列号和数据长度,将自己下一步接收的序号作为确认应答发送回去。

这样,通过序列号和确认应答号,就可以实现TCP的可靠传输。

上面谈到了重发数据情况,那什么时候重发数据呢? 这个时间怎么计算?

也就是说,这个重发的时间怎么确定?什么时候开始计时的?

二:重发和重发超时时间

重传定时器

要实现超时重发,就是在发送完一组数据时,就立即给这组数据设置一个超时定时器。如果定时器到期之前收到了对端的确认号,就撤销重传超时定时器。

超时时间怎么设置:

  • 如果设置的长一点,重发数据就变慢了,效率就变差了;
  • 如果设置的短一点,可能会导致数据还没丢就重发了。这样的话,重发数据就变快了,自然会增加网络负担,导致网络拥塞,一拥塞,就会导致更多的超时,超时又导致更多的重发。

所以这个时间的设置就变得很重要了。

先看看发送数据的几个步骤:

  1. 发送端发送数据,并启动重传定时器
  2. 等待对端的应答ACK号
  3. 重传定时器到期

这里有几个时间的概念:

  1. RTT(Round Trip Time):发送一个数据包到收到对端的ACK所花费的时间
  2. RTO(Retransmission TimeOut): 发送数据包,启动重传定时器,重传定时器到期所花费的时间,称为RTO

网络又是复杂的,由各种主机,路由器,网络等组成。所以这个重传时间RTO只能动态来计算了。

经过一些计算机专家的研究,它是根据RTT来动态计算的。

重传时间算法

第一种经典算法:RFC793

  1. 首先计算一个平滑的RTT称为SRTT, alpha是一个平滑因子,取值为0.8或者0.9
SRTT = ( ALPHA * SRTT ) + ((1-ALPHA) * RTT)
  1. 基于SRTT,计算出对应的RTO
RTO = min[UBOUND, max[LBOUND, (BETA*SRTT)]

其中UBOUND是最大值,一般情况下为120s,LBOUND是最小重传值,一般情况下为1s,Beta也是一个因子,建议取值为1.3~2.0.

这个算法来自 RFC793

但是这个算法在目标Linux中没有使用,原因是存在不足。有文章指出:从公式可以看到在经典的RTO计算方法中会有一个很大的问题,就是当RTT对RTO的影响太小了,也就是说经典的RTO计算方法在RTT变化比较大的网络中,会表现的非常不好的。

第二种算法:Jacobaon/Karels 算法

1988年,Van Jacobson和Karels在Congestion Avoidance and Control这篇论文中提出一种新的算法RFC6298,这里对于rtt的采样,多添加了一个因素,那就是均差(mean deviation),而这里并不是传统意义上的均差,使用的平均数其实就是我们在经典方法中的srtt。

第一次RTO计算方法, 假设RTT = R

1. SRTT = R

2. RTTVAR = R/2

3. RTO = SRTT + max(G, K*RTTVAR) , K = 4

后续的RTO计算,假设当前的RTT为R'

RTTVAR = (1 - beta)*RTTVAR + beta*|SRTT - R'|
//计算平滑RTT和真实RTT的差距,切记这个地方的SRTT是上一次的SRTT
SRTT = (1 - alpha)*SRTT + alpha*R'
//计算平滑RTT, 及是SRTT
RTO = SRTT + max(G, K*RTTVAR)
//计算 RTO

alpha = 1/8  beta = 1/4,值得指出的是这个算法在目前的Linux协议栈中应用

第二种算法到底有啥好处,可以去查看相关文章看看

参考

TCP/IP的确认号,序列号和超时重传的学习笔记的更多相关文章

  1. TCP/IP他人笔记学习--地址收录

    <TCP/IP详解,卷1:协议>学习笔记——1. 概述   http://www.blogjava.net/amigoxie/archive/2007/08/22/138674.html ...

  2. TCP/IP 笔记 - 超时和重传

    TCP协议为了提供可靠的数据传输服务,会启动数据重传来解决下层网络层(IP)可能出现的数据包丢失. 超时重传介绍 TCP重传由两套独立机制来完成重传,基于时间的超时重传(RTO,TCP发送数据时会设置 ...

  3. TCP/IP原理浅析

    TCP/IP概述 TCP/IP起源于1969年美国国防部(DOD:The United States Department Of Defense)高级研究项目管理局(APRA:AdvancedRese ...

  4. TCP/IP漫游

    TCP/IP漫游 TCP/IP是互联网的基础协议栈,它包括大大小小几十个协议.本篇文章主要涉及到就是HTTP.TCP.IP协议.我们经常学的网络模型是七层或者五层,实际上一般认为一共只有四层就可以了. ...

  5. 流媒体 8——因特网 tcp/ip

    1 因特网 1.1 因特网的结构 组成因特网的子网之间在物理上的相互连接都是通过网关设备实现的.通过网关设备互相连接在一起的不同的网络通常称为子网 (subnetwork),因为它们是大网络之中的网络 ...

  6. 11-2 TCP/IP协议栈

    TCP/IP协议栈 Transmission Control Protocol/Internet Protocol传输控制协议/因特网互联协议 TCP/IP是一个Protocol Stack,包括TC ...

  7. TCP/IP入门(3) --传输层

    原文:http://blog.csdn.net/zjf280441589/article/category/1854365 传输层的主要功能 1)传输层为应用进程之间提供端到端的逻辑通信(网络层是为主 ...

  8. TCP/IP详解

    第一篇 TCPIP协议详解 第1章 TCPIP协议族 第2章 IP协议详解 第3章 TCP协议详解 第4章 TCP/IP通信案例:访问Internet上的Web服务器 一.TCP/IP协议族 TCP/ ...

  9. TCP/IP协议(二)

    2014-09-04 11:03:27   注:关于seq 和 ack 的理解,seq为发送的字节的第一个序号,一直累加,ack接收字节的最后一个序号+1,建立连接和结束连接时的SYN.FIN标志位占 ...

  10. TCP/IP详解学习笔记(13)-- TCP连接的建立与终止

    1.TCP连接的建立            设主机B运行一个服务器进程,它先发出一个被动打开命令,告诉它的TCP要准备接收客户进程的连续请求,然后服务进程就处于听的状态.不断检测是否有客户进程发起连续 ...

随机推荐

  1. [转帖]Nginx优化与防盗链

    目录 一.配置Nginx隐藏版本号 1.第一种方法修改配置文件 2.第二种方法修改源码文件,重新编译安装 二.修改Nginx用户与组 三.配置Nginx网页缓存时间 四.实现Nginx的日志分割 五. ...

  2. [转帖]MySQL ALTER TABLE: ALTER vs CHANGE vs MODIFY COLUMN

    https://www.cnblogs.com/pachongshangdexuebi/p/5029152.html ALTER COLUMN 语法: ALTER [COLUMN] col_name ...

  3. [转帖]iometer - 性能压力测试工具

    <存储工具系列文章>主要介绍存储相关的测试和调试工具,包括不限于dd.fio.vdbench.iozone.iometer.cosbench等性能负载工具,及strace等调试工具. 1 ...

  4. [转帖]Linux性能测试之unixbench

    https://www.modb.pro/db/487945 大家好,昨天为大家带来了一篇关于在Linux下性能测试的文章<性能测试之LTP>,今天继续为大家推荐系列工具之unixbenc ...

  5. Mark 一下 Redisson 可能需要升级版本

    貌似有bug 我们高并发的情况下貌似遇到了 https://github.com/redisson/redisson/issues/2299

  6. uni-app快速导入自己需要的插件

    在uni-app中快速导入自己需要的插件 在uni-app的官网上;找到自己需要的插件: 然后点击右侧顶部的[使用HX导入]这一步的前提是你必须要用自己的账好登录: 然后选择你要导入哪一个项目 然后就 ...

  7. ClickHouse(08)ClickHouse表引擎概况

    目录 合并树家族 日志引擎系列 集成的表引擎 其他特殊的引擎 资料分享 参考文章 目前ClickHouse的表引擎主要有下面四个系列,合并树家族.日志引擎系列.集成的表引擎和其他特殊的引擎. 合并树家 ...

  8. 手撕Vuex-实现getters方法

    经上一篇章介绍,完成了实现共享数据的功能,实现方式是在 Store 构造函数中将创建 Store 时将需要共享的数据添加到 Store 上面,这样将来我们就能通过 this.$store 拿到这个 S ...

  9. Python 探索性数据分析工具(PandasGUI,Pandas Profiling,Sweetviz,dtale)以及学术论文快速作图science.mplstyle

    如果探索的数据集侧重数据展示,可以选PandasGUI:如果只是简单了解基本统计指标,可以选择Pandas Profiling和Sweetviz:如果需要做深度的数据探索,那就选择dtale. 1. ...

  10. 9.0 Python 内置模块应用

    Python 是一种高级.面向对象.通用的编程语言,由Guido van Rossum发明,于1991年首次发布.Python 的设计哲学强调代码的可读性和简洁性,同时也非常适合于大型项目的开发.Py ...