TCP是可靠传输。可靠之一体现在收到数据后,返回去一个确认。但是不能完全避免的是,数据和确认都可能丢失。解决这个办法就是,提供一个发送的重传定时器:如果定时器溢出时还没收到确认,它就重传这个报文段。

想法是完美的,关键之处在于超时和重传的策略,即怎么决定超时间隔和如何确定重传的频率。

书中举了一个简单的超时重传例子:

如图:

比如A往B传,传了一部分数据后,把B的网线拔了(前边讲过,如果不传数据的话,双方没法知道这个连接已经断了)。然后开始A再给B发数据,此时tcpdump出来发现,连续重传了一个报文段:时间间隔分别是,1.013s, 3, 6, 12, 24 和多个64s...最后发了个复位报文段表示我放弃了。。(从第一次开始发这个报文段,到最后发一个复位段的时间差大约是9分钟,这个9分钟一般在TCP实现中是不变的)。

往返时间测量:
TCP的超时时间很大程度上是依赖报文段的往返时间。因此测量往返时间显得尤为重要。
因为链路上的网络流量或者路由器等的存在,往返时间一般不会是一成不变的,可能会经常发生变化。
最初的TCP规范这样协议:RTT(Round-Trip Time)表示往返时间,用M表示测量到的RTT。
更新过的RTT = 0.9*RTT + 0.1*M 表示,我估计新的往返时间将是,0.9倍的之前的RTT + 0.1倍的新测量的RTT。(0.9叫平滑因子)
得到了新的估计RTT,推荐的重传超时时间RTO(Retransmission TimeOut)的值应该设置为
RTO = RTT*b (这里的b是一个推荐值为2的时延离散因子)。超时时间就是大约2倍的往返时间。

以上这个计算超时时间的方法存在缺陷,[Jacobson 1988] 作出了详细分析,当RTT变化范围比较大的时候,这个方法显得力不从心了,可能会引起不必要的重传。这样当网络负载比较高的时候,再重传会火上浇油...
     这就又有了新的方法计算重传超时时间:
前边说到如果RTT变化范围较大时,容易发生不必要重传。学过数学的都会知道,方差可以体现出波动大小。这个方法就是用到了方差来均衡下。
这里有个公式用来计算RTO,懂的原理就好了,这个计算RTO的公式依赖于估计的RTT和均值偏差(逼近与标准差),而最初的方法则使用了被平滑的RTT的一个倍数(b=2)。这块知道是这么个事就好~

往返时间RTT的测量:
如图:

左边的时间轴上有三个括号,它们表明为进行RTT计算对哪些个报文段进行了计时,并不是所有的报文段都被计时。在发送一个报文段时,如果给定连接的重传定时器已经被使用,则该报文段不被计时。如图报文段4或者报文段7都没有参与计时。
对每个连接而言,除了这个滴答计数器,报文段中数据的起始序号也被记录下来。当收到一个包含这个序号的确认后,该定时器就被关闭。如果ACK到达时数据没有被重传,则被平滑的RTT和被平滑的均值偏差将基于这个新测量进行更新。

在每次调用500 ms的TCP的定时器例程时,就增加一个计数器来完成计时。这意味着,如果一个报文段的确认在它发送550 ms后到达,则该报文段的往返时间RTT将是1个滴答(即500 ms)或是2个滴答(即1000 ms)。
如图RTT测量和时钟滴答:

-拥塞举例:
主机slip总是通告窗口大小为4096,而主机vangogh则通告窗口为8192。
如图:

报文段45丢失了,报文段58是正常接收43的报文段给出的确认,然后接着接收主机连续发了8个ack 6657。可以看出是重发第三次(除了正常确认的中第3个)时,发送主机重传发送了63报文段。
这收到第三个ack才重传也是算法中要求的,当收到第3个时,就假定一个报文段已经丢失并重传自那个序号起的一个报文段。这就是Jacobson的快速重传算法。
值得注意的是,在重传后(报文段63),发送方继续正常的数据传输(报文段67、69和71)。TCP不需要等待对方确认重传。

这里再分析一下接收端是怎么处理的: 当按序收到正常数据(报文段43)后,接收TCP将255个字节的数据交给用户进程。但下一个收到的报文段(报文段46)是失序的(数据的开始序号 6913 并不是下一个期望的序号 6657)。TCP保存256字节的数据,并返回一个已成功接收数据的最大序号加1(6657)的ACK。被vangogh接收到的后面7个报文段(48, 50, 52, 54, 55, 57和59)也是失序的,接收方TCP保存这些数据并产生重复ACK(TCP实现没法告诉对方,我就缺某某个报文段,它只能告诉发送方我的确认序号一直是这个)。
当缺少的报文段(报文段 63)到达时,接收方TCP在其接收缓存中组合好第6657~8960字节的数据,并将这2304字节的数据交给用户进程。所有这些数据在报文段72中进行确认。
值得注意的是,此时该ACK通告窗口大小为5888(8192-2304,原来的通告窗口大小是8192),这是因为用户进程此时还没有读取出这些缓存中的字节。

-拥塞避免:
该算法假定由于分组受到损坏引起的丢失是非常少的(远小于1%),因此分组丢失就意味着在源主机和目的主机之间的某处网络上发生了拥塞。
有两种分组丢失的指示:发生超时和接收到重复的确认(如果使用超时作为拥塞指示,则需要使用一个好的RTT算法)。
前边讲过慢启动,拥塞避免算法和慢启动算法是两个目的不同、独立的算法。但是当拥塞发生时,我们希望降低分组进入网络的传输速率,于是可以调用慢启动来作到这一点。在实际中这两个算法通常在一起实现。

-快速重传和快速恢复算法:
在前边拥塞举例时,观察到第三个ack过来,发送端才进行重传。这是因为:由于我们不知道一个重复的ACK是由一个丢失的报文段引起的,还是由于仅仅出现了几个报文段的重新排序,因此我们等待少量重复的ACK到来。假如这只是一些报文段的重新排序,则在重新排序的报文段被处理并产生一个新的ACK之前,只可能产生1 ~ 2个重复的ACK。 如果一连串收到3个或3个以上的重复ACK,就非常可能是一个报文段丢失了。于是我们就重传丢失的数据报文段,而无需等待超时定时器溢出。这就是快速重传算法。
接下来收到重传的ACK以前,发送了3个新的数据的报文段(报文段67,69和71)。执行的不是慢启动算法而是拥塞避免算法。这就是快速恢复算法。在这种情况下没有执行慢启动的原因是由于收到重复的ACK不仅仅告诉我们一个分组丢失了,而是在收发两端之间仍然有流动的数据(由于接收方只有在收到另一个报文段时才会产生重复的ACK,而该报文段已经离开了网络并进入了接收方的缓存),因此我们不想执行慢启动来突然减少数据流。

重新分组:
当TCP超时并重传时,它不一定要重传同样的报文段。而是TCP允许进行重新分组而发送一个较大的报文段,这将有助于提高性能(当然,这个较大的报文段不能够超过接收方声明的MSS)。
如图:

第3个发送前,断开网线。开始发送3,此时发生了重传,在放弃连接前,又键入了几个字节。然后插上网线,发现第8行,是把前边两次的分组组装成了一个分组发过去的。

TCP的超时重传...end

-

TCP/IP协议--TCP的超时和重传的更多相关文章

  1. TCP/IP协议 | TCP协议 | UDP协议 | 三次握手四次挥手

    TCP/IP协议不仅仅指的是TCP 和IP两个协议,而是指一个由FTP.SMTP.TCP.UDP.IP等协议构成的协议簇, 只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP ...

  2. TCP/IP协议——TCP/IP协议栈及框架

    TCP/IP协议同ISO/OSI模型一样,也可以安排成栈形式.但这个栈不同于ISO/OSI版本,比ISO/OSI栈少,所以又称之为短栈.另外,需要知道的是:TCP/IP协议栈只是许多支持ISO/OSI ...

  3. TCP/IP协议--TCP协议概括和TCP连接的建立和终止

    TCP提供一种面向连接的.可靠的字节流服务.面向连接指,发送和接收方在交换数据前必须建立一个TCP连接.顺便说下,一个TCP连接只有两方,因此广播和多播是不能应用于TCP的.字节流指,两个应用程序通过 ...

  4. TCP/IP协议--TCP的交互数据流和成块数据流

    前边讲了TCP连接的建立和终止,分别要三次握手和四次通信.这些报文段都只包含首部,没有数据部分.    这里就讲讲数据传送的一些细节.一个TCP连接建立成功以后,就可以开始传送数据了~ 一般TCP数据 ...

  5. TCP/IP协议、三次握手、四次挥手

    1.什么是TCP/IP协议 TCP/IP 是一类协议系统,它是用于网络通信的一套协议集合. 传统上来说 TCP/IP 被认为是一个四层协议 1) 网络接口层: 主要是指物理层次的一些接口,比如电缆等. ...

  6. C# HTTP1.0 1.1 2.0与HTTPS 、TCP/IP协议的UDP与TCP、 Socket介绍与WebSocket

    一.HTTP1.0 1.1 2.0和HTTPS 1.HTTP协议是什么? HTTP协议是超文本传输协议的缩写,英文是Hyper Text Transfer Protocol.它是从WEB服务器传输超文 ...

  7. TCP/IP协议详解内容总结

    TCP/IP协议 TCP/IP不是一个协议,而是一个协议族的统称.里面包括IP协议.IMCP协议.TCP协议. TCP/IP分层:   这里有几个需要注意的知识点: 互联网地址:也就是IP地址,一般为 ...

  8. OSI协议和TCP/IP协议笔记

    1.OSI协议: 第7层应用层:OSI中的最高层.是用户与网络的接口.该层通过应用程序来完成网络用户的应用需求,如文件传输.收发电子邮件等.在此常见的协议有:HTTP,HTTPS,FTP,TELNET ...

  9. TCP/IP协议,,OSI的七层参考模型,HTTP请求响应机制

    一.TCP/IP协议 TCP/IP是Transmission Control Protocol/Internet Protocol的简写,中译名为传输控制协议/因特网互联协议,又名网络通讯协议,是In ...

随机推荐

  1. SD从零开始62-63,不完全日志,业务伙伴及业务伙伴确定

    [原创] SD从零开始62 不完全日志 不完全日志Incompletion log 一个不完全日志是销售凭证中对你公司重要的而还没有在系统中输入的所有数据的清单: 你可以在配置中为不完全日志定义这些数 ...

  2. Oracle绑定变量在C#.NET中的应用及意义

    一. 什么是绑定变量 绑定变量(bind variable) : select * from emp where empno=:empno; 是用户放入查询中的占位符,它会告诉Oracle“我会随后为 ...

  3. Linux高可靠技术

    1.进程挂死时,有后台监控程序检测重新拉起. 2.进程占用系统资源超过ulimit限定的资源时,会被ulimit杀死,同时配合后台监控程序,重新拉起进程,实现进程可靠性. 3.Linux系统的高可靠性 ...

  4. 编写xml文件不当时会出现R文件找不到情况

    1,先检查xml文件是否报错,报错的话直接找到报错行. 2,xml文件若不报错,可能是文本值得格式输入错误 比如android:text=“<0.5km”,此时的小于号就会引发错误,导致R文件找 ...

  5. [软件逆向]实战Mac系统下的软件分析+Mac QQ和微信的防撤回

      0x00  一点废话 最近因为Mac软件收费的比较多,所以买了几款正版软件,但是有的软件卖的有点贵,买了感觉不值,不买吧,又觉得不方便,用别人的吧,又怕不安全.于是我就买了正版的Hopper Di ...

  6. php解决前后端验证字符串长度不一致

    前端代码 function getStrleng(str){ var myLen =0; for(var i=0;i<str.length;i++){ if(str.charCodeAt(i)& ...

  7. 【PAT】B1066 图像过滤(15 分)

    注意输出是占三位,其他的挺水 #include<stdio.h> #include<algorithm> using namespace std; int main(){ in ...

  8. Linux之特殊的环境变量IFS以及如何删除带有空格的目录

    1.IFS是什么? Linux下有一个特殊的环境变量叫做IFS,叫做内部字段分隔符(internal field separator).IFS环境变量定义了bash shell用户字段分隔符的一系列字 ...

  9. ES5数组的遍历方式

    /* 遍历数组 */ var arr=[1,2,3,43,55,66,77,99]; /* 遍历数组 function(item,index) */ arr.forEach(function(item ...

  10. golang的json序列化问题

    首先看一段代码: package main import ( "encoding/json" "fmt" ) type Result struct { //st ...