当前位置:网站首页>TCP如何处理三次握手和四次挥手期间的异常
TCP如何处理三次握手和四次挥手期间的异常
2022-06-25 11:29:00 【Hello,C++!】
1、TCP 三次握手期间的异常
我们先来看看 TCP 三次握手是怎样的。

1.1、第一次握手丢失了,会发生什么?
当客户端想和服务端建立 TCP 连接的时候,首先第一个发的就是 SYN 报文,然后进入到 SYN_SENT 状态。
在这之后,如果客户端迟迟收不到服务端的 SYN-ACK 报文(第二次握手),就会触发超时重传机制。
不同版本的操作系统可能超时时间不同,有的 1 秒的,也有 3 秒的,这个超时时间是写死在内核里的,如果想要更改则需要重新编译内核,比较麻烦。
当客户端在 1 秒后没收到服务端的 SYN-ACK 报文后,客户端就会重发 SYN 报文,那到底重发几次呢?
在 Linux 里,客户端的 SYN 报文最大重传次数由 tcp_syn_retries内核参数控制,这个参数是可以自定义的,默认值一般是 5。
通常,第一次超时重传是在 1 秒后,第二次超时重传是在 2 秒,第三次超时重传是在 4 秒后,第四次超时重传是在 8 秒后,第五次是在超时重传 16 秒后。没错,每次超时的时间是上一次的 2 倍。
当第五次超时重传后,会继续等待 32 秒,如果服务端仍然没有回应 ACK,客户端就不再发送 SYN 包,然后断开 TCP 连接。
所以,总耗时是 1+2+4+8+16+32=63 秒,大约 1 分钟左右。
1.2、第二次握手丢失了,会发生什么?
当服务端收到客户端的第一次握手后,就会回 SYN-ACK 报文给客户端,这个就是第二次握手,此时服务端会进入 SYN_RCVD 状态。
第二次握手的 SYN-ACK 报文其实有两个目的 :
- 第二次握手里的 ACK, 是对第一次握手的确认报文;
- 第二次握手里的 SYN,是服务端发起建立 TCP 连接的报文;
所以,如果第二次握手丢了,就会发送比较有意思的事情,具体会怎么样呢?
因为第二次握手报文里是包含对客户端的第一次握手的 ACK 确认报文,所以,如果客户端迟迟没有收到第二次握手,那么客户端就觉得可能自己的 SYN 报文(第一次握手)丢失了,于是客户端就会触发超时重传机制,重传 SYN 报文。
然后,因为第二次握手中包含服务端的 SYN 报文,所以当客户端收到后,需要给服务端发送 ACK 确认报文(第三次握手),服务端才会认为该 SYN 报文被客户端收到了。
那么,如果第二次握手丢失了,服务端就收不到第三次握手,于是服务端这边会触发超时重传机制,重传 SYN-ACK 报文。
在 Linux 下,SYN-ACK 报文的最大重传次数由 tcp_synack_retries内核参数决定,默认值是 5。
因此,当第二次握手丢失了,客户端和服务端都会重传:
- 客户端会重传 SYN 报文,也就是第一次握手,最大重传次数由
tcp_syn_retries内核参数决定。; - 服务端会重传 SYN-AKC 报文,也就是第二次握手,最大重传次数由
tcp_synack_retries内核参数决定。
1.3、第三次握手丢失了,会发生什么?
客户端收到服务端的 SYN-ACK 报文后,就会给服务端回一个 ACK 报文,也就是第三次握手,此时客户端状态进入到 ESTABLISH 状态。
因为这个第三次握手的 ACK 是对第二次握手的 SYN 的确认报文,所以当第三次握手丢失了,如果服务端那一方迟迟收不到这个确认报文,就会触发超时重传机制,重传 SYN-ACK 报文,直到收到第三次握手,或者达到最大重传次数。
注意,ACK 报文是不会有重传的,当 ACK 丢失了,就由对方重传对应的报文。
2、TCP 四次挥手期间的异常
我们再来看看 TCP 四次挥手的过程。

2.1、第一次挥手丢失了,会发生什么?
当客户端(主动关闭方)调用 close 函数后,就会向服务端发送 FIN 报文,试图与服务端断开连接,此时客户端的连接进入到 FIN_WAIT_1 状态。
正常情况下,如果能及时收到服务端(被动关闭方)的 ACK,则会很快变为 FIN_WAIT2 状态。
如果第一次挥手丢失了,那么客户端迟迟收不到被动方的 ACK 的话,也就会触发超时重传机制,重传 FIN 报文,重发次数由 tcp_orphan_retries 参数控制。
当客户端重传 FIN 报文的次数超过 tcp_orphan_retries 后,就不再发送 FIN 报文,直接进入到 close 状态。
2.2、第二次挥手丢失了,会发生什么?
当服务端收到客户端的第一次挥手后,就会先回一个 ACK 确认报文,此时服务端的连接进入到 CLOSE_WAIT 状态。
在前面我们也提了,ACK 报文是不会重传的,所以如果服务端的第二次挥手丢失了,客户端就会触发超时重传机制,重传 FIN 报文,直到收到服务端的第二次挥手,或者达到最大的重传次数。
这里提一下,当客户端收到第二次挥手,也就是收到服务端发送的 ACK 报文后,客户端就会处于 FIN_WAIT2 状态,在这个状态需要等服务端发送第三次挥手,也就是服务端的 FIN 报文。
对于 close 函数关闭的连接,由于无法再发送和接收数据,所以FIN_WAIT2 状态不可以持续太久,而 tcp_fin_timeout 控制了这个状态下连接的持续时长,默认值是 60 秒。
这意味着对于调用 close 关闭的连接,如果在 60 秒后还没有收到 FIN 报文,客户端(主动关闭方)的连接就会直接关闭。
2.3、第三次挥手丢失了,会发生什么?
当服务端(被动关闭方)收到客户端(主动关闭方)的 FIN 报文后,内核会自动回复 ACK,同时连接处于 CLOSE_WAIT 状态,顾名思义,它表示等待应用进程调用 close 函数关闭连接。
此时,内核是没有权利替代进程关闭连接,必须由进程主动调用 close 函数来触发服务端发送 FIN 报文。
服务端处于 CLOSE_WAIT 状态时,调用了 close 函数,内核就会发出 FIN 报文,同时连接进入 LAST_ACK 状态,等待客户端返回 ACK 来确认连接关闭。
如果迟迟收不到这个 ACK,服务端就会重发 FIN 报文,重发次数仍然由 tcp_orphan_retries 参数控制,这与客户端重发 FIN 报文的重传次数控制方式是一样的。
2.4、第四次挥手丢失了,会发生什么?
当客户端收到服务端的第三次挥手的 FIN 报文后,就会回 ACK 报文,也就是第四次挥手,此时客户端连接进入 TIME_WAIT 状态。
在 Linux 系统,TIME_WAIT 状态会持续 60 秒后才会进入关闭状态。
然后,服务端(被动关闭方)没有收到 ACK 报文前,还是处于 LAST_ACK 状态。
如果第四次挥手的 ACK 报文没有到达服务端,服务端就会重发 FIN 报文,重发次数仍然由前面介绍过的 tcp_orphan_retries 参数控制。
是吧,TCP 聪明着很!
边栏推荐
- Leetcode 1249. 移除无效的括号(牛逼,终于做出来了)
- Big Endian 和 Little Endian
- Technical practice and development trend of video conference all in one machine
- 4 life distributions
- 过拟合原因及解决
- 基于超算平台气象预警并行计算架构研究
- 【上云精品】节能提效!加速纺织业“智造”转型
- Spannable and editable, spannablestring and spannablestring
- 2022 PMP project management examination agile knowledge points (2)
- Dynamic programming to solve stock problems (Part 1)
猜你喜欢

CMU puts forward a new NLP paradigm - reconstructing pre training, and achieving 134 high scores in college entrance examination English

Redis6 note02 configuration file, publish and subscribe, new data type, jedis operation

Course paper + code and executable EXE file of library information management system based on C language

牛客网:旋转数组

Ladder Side-Tuning:预训练模型的“过墙梯”

Double tampon transparent cryptage et décryptage basé sur le cadre minifilter

芯片的发展史和具体用途以及结构是什么样的

Research on parallel computing architecture of meteorological early warning based on supercomputing platform

金仓KFS数据集中场景(多对一)部署

SQL注入漏洞(类型篇)
随机推荐
SQL注入漏洞(繞過篇)
某APP中模拟器检测分析
查询法,中断法实现USART通信
翌圣生物冲刺科创板:25%收入来自新冠产品销售 拟募资11亿
relu与sigmod的比较
基於Minifilter框架的雙緩沖透明加解密驅動 課程論文+項目源碼
Course paper + code and executable EXE file of library information management system based on C language
Causes and solutions of over fitting
Redis6笔记02 配置文件,发布和订阅,新数据类型,Jedis操作
SQL injection vulnerability (type chapter)
Vulnérabilité à l'injection SQL (contournement)
Crawler scheduling framework of scratch+scratch+grammar
C disk uses 100% cleaning method
Comparison between relu and SIGMOD
记一次有趣的逻辑SRC挖掘
[maintain cluster case set] gaussdb query user space usage
动态规划解决股票问题(上)
Handler、Message、Looper、MessageQueue
Handler、Message、Looper、MessageQueue
Technical practice and development trend of video conference all in one machine