TCP协议探究(二):超时与重试
1 概述
- TCP提供可靠的运输层。
- 可靠性保证之一:确认从另一端收到的数据。
- 但数据和确认都有可能会丢失。TCP通过在发送时设置一个定时器来解决这种问题。
- 如果当定时器溢出时还没有收到确认,它就重传该数据。
- TCP对于每个连接TCP管理4个不同的定时器:
- 重传定时器:使用于当希望收到另一端的确认。
- 2MSL定时器:测量一个连接处于TIME_WAIT状态的时间。
- 坚持(persist)定时器:使窗口大小信息保持不断流动,即使另一端关闭了其接收窗口
- 保活(keepalive)定时器:用于检测一个空闲连接的另一端何时崩溃或重启。
2 TCP的状态机

超时情况:
建立连接时SYN超时:
- client主动打开连接,发送SYN报文给server
- server收到后被动打开,发送SYN+ACK报文给client,此时client直接下线
- 导致server无法收到client的ACK报文,即该TCP连接既没有建立也没有断开,所以server又会重传SYN+ACK报文
- 在Linux下,默认重试次数为5次,重试的间隔时间从1s开始每次都翻倍,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s,总共31s,第5次发出后还要等32s都知道第5次也超时了,所以,总共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 2^6 -1 = 63s,TCP才会把断开这个连接。
SYN Flood:
- 恶意伪造大量的TCP连接并断开Client,导致Server维持了大量的TCP连接,且需要63秒后才会断开,即63秒内的TCP连接数足够多时,Server将承受不住,导致正常的连接不能处理。
- 处理方案:
- 减少Server的重试次数
- 增大SYN的连接数
- 处理不过来的连接直接丢弃
ISN的初始化:
- ISN不是每次建立建立连接时都从1开始
- 问题:因为如果从1开始,client发送了30个segment给server,此时网络断开,过会client重连,又使用ISN=1来发送报文,但之前的报文已经送到了,即server认为client的ISN(初始化序列号)为30,但是实际上为1。
- 解决方法:ISN会和一个假的时钟绑在一起,这个时钟会在每4微秒对ISN做加一操作,直到超过2^32,又从0开始。
- MSL(Maximum Segment Lifetime):TCP段的最大存活时间,4ms*2^32=4.55小时,即TCP段存活时间不超过4.55小时就不会重用ISN。
MSL 和 TIME_WAIT:
- 在TCP的状态图中,从TIME_WAIT状态到CLOSED状态,有一个超时设置,这个超时设置是 2 * MSL。
- TIME_WAIT(2 * MSL):确保有足够的时间让对端收到了ACK,如果被动关闭的那方没有收到Ack,就会触发被动端重发FIN,一来一去正好不超过2 * MSL。
- 有足够的时间让这个连接不会跟后面的连接混在一起(有些路由器会缓存IP数据包,导致连接被重用)。
3 TCP重试机制(发送方)
(1)概述
TCP要保证所有的数据包都到达,必需有重传机制。
发送端发了1,2,3,4,5一共五份数据,接收端收到了1,2,于是回ack 3,然后收到了4(注意此时3没收到),此时的TCP会怎么办?
(2)超时重传机制
- 不回ACK,一直等待SN=3的到来,而发送方一直收不到3的ACK,就会超时重传3.
- 这种方式会有严重的问题,那就是死等3,所以导致4和5已经被收到了,而发送方也完全不知道(没有收到ACK),所以发送方可能会悲观地认为也丢了(即有可能导致4和5的重传)。
- 发送方的两种选择:
- 仅仅重传timeout的包,节约宽带,但是需要继续等待后续报文ACK或者timeout重传(效率低)。
- 重传timeout后的所有包,浪费宽带,而且可能做了无用功。
(3)快速重传机制
- 如果发送方发出了1,2,3,4,5份数据,1先到了,于是就ack回2,结果2因为某些原因没收到。3到达了,ack也回2,后面的4和5都到了,ack也回2(2没有收到)。
- 于是发送端收到了三个ack=2的确认,知道了2还没有送达,于是重传2(或者2之后的所有包)。然后接收端收到了2,此时3,4,5都收到了,于是ack回6。
- 优点:不需要等待ACK超时,但是仍然没有解决是重传2还是重传2与之后的所有包。
(4)SACK 方法

- SACK回复可以告知发送端需要排除哪些报文进行发送
- 该协议需要两边都支持。
强烈建议看看
叔的文章
参考:https://coolshell.cn/articles/11564.html
TCP协议探究(二):超时与重试的更多相关文章
- 高并发服务器建议调小 TCP 协议的 time_wait 超时时间。
1. [推荐]高并发服务器建议调小 TCP 协议的 time_wait 超时时间. 说明:操作系统默认 240 秒后,才会关闭处于 time_wait 状态的连接,在高并发访问下,服 务器端会因为处于 ...
- TCP协议探究(一):报文格式与连接建立终止
一 TCP:传输控制协议报文格式 1 TCP服务 提供面向连接.可靠的字节流服务 面向连接意味着两方通信,不支持多播和广播 可靠性的支持: 应用数据被分割成TCP认为最适合发送的数据块.由TCP传递给 ...
- TCP协议探究(四):定时器
1 概述 重传定时器:使用于当希望收到另一端的确认. 坚持(persist)定时器:使窗口大小信息保持不断流动,即使另一端关闭了其接收窗口 保活(keepalive)定时器:用于检测一个空闲连接的另一 ...
- TCP协议探究(三):RTT、滑动窗口和阻塞处理
1 RTT算法 1.1 概述 上一节说了重传机制需要设置一个重传超时值(RTO,Retransmission TimeOut),RTO设长了,重发太慢:设短了,可能导致包没有丢,就重发了,可能导致雪崩 ...
- Wireshark分析之TCP协议(二)
(1)TCP首部格式 源端口: 用来传输数据报的端口 目标端口: 数据包将要发送到的端口 序号: 用来表示一个TCP片段.这个值用来表示数据流中的部分数据没有丢失 确认号: 表示通信中希望从另一 ...
- 高并发服务器建议调小 TCP 协议的 time_wait 超时时间
说明:操作系统默认 240 秒后,才会关闭处于 time_wait 状态的连接,在高并发访问下,服 务器端会因为处于 time_wait 的连接数太多,可能无法建立新的连接,所以需要在服务器上 调小此 ...
- TCP/UDP协议(二)
面试问题:Tcp/Udp协议是什么,各有什么异同点,各自的使用场景? Tcp协议(传输控制协议) tcp是面向连接的协议,在收发数据之前,必须与对方建立可靠的连接: 三次握手:简单形象通俗描述: 主机 ...
- 网络编程(二)--TCP协议、基于tcp协议的套接字socket
一.TCP协议(Transmission Control Protocol 传输控制协议) 1.可靠传输,TCP数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常TCP数据包的长度不会 ...
- 网络编程(二)——TCP协议、基于tcp协议的套接字socket
TCP协议与基于tcp协议的套接字socket 一.TCP协议(流式协议) 1.可靠传输,TCP数据包没有长度限制,理论上可以无限长,但是为了保证网络的效率,通常TCP数据包的长度不会超过IP数据包的 ...
随机推荐
- JAVA安全漫谈1-8笔记
一.反射篇1 classloader就是java的类加载器,告诉虚拟机如何加载这个类.默认情况下根据类名来加载类,类名必须是完整路径 public class class_init { { Syste ...
- appdomain概念与应用
用appcmd命令显示w3wp.exe进程,很多时候一个应用程序池负责创建一个w3wp.exe进程与之对应,可能还有时候是创建多个w3wp.exe,有待验证. c:\Windows\System32\ ...
- jQuery 的on()方法
jQuery 的on()方法 一.总结 一句话总结: 1.普通添加事件:$("a").on("click", function () {执行的代码}) 2.未创 ...
- 如何规避同时使用v-if与v-for?
先将结果过滤,再用v-if循环 遇到问题:使用Vue -computed传参数不成功, 后来将参数放在compute里面方法名里再构造参数进行传递
- vue2.0+vue-video-player实现hls播放的案例
1. 安装依赖. npm install vue-video-player --save 2. 在main.js引入vue-video-player. import VueVideoPlayer fr ...
- 关于Java 8新引入语法特性的简要说明
Java 8在语法上的主要改进就是新增了Lambda Expression以及Method Reference.由于官方网站的介绍稍显罗嗦,而且例子也有些复杂.我这里将提供一些更为浅显.直观的例子来帮 ...
- Hibernate fetch相关
fetch=FetchType.LAZY 时,spring boot jackson 返回数据时会出错. 可配置使用Hibernate4Module 帮助解决: @Configurationpubli ...
- tomcat配置使用log4j管理日志
从tomcat官网下载和tomcat对应的tomcat-juli.jar和tomcat-juli-adapters.jar,从log4j官网下载log4j的jar包(我用的是log4j-1.2.17. ...
- [dart学习]第七篇:类(构造函数)
前言:楼主平时基本没有使用过异常处理,所以对异常的认知可能不够准确,这里就不翻译异常的相关内容了,大家可以去官网自行阅读介绍,地址 https://dart.dev/guides/language/l ...
- Python将多个excel表格合并为一个表格
Python将多个excel表格合并为一个表格 生活中经常会碰到多个excel表格汇总成一个表格的情况,比如你发放了一份表格让班级所有同学填写,而你负责将大家的结果合并成一个.诸如此类的问题有很多.除 ...