TCP连接的状态详解以及故障排查(四)

news/2024/11/20 9:42:02/

TCP连接的终止(四次握手释放)

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。

首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。

建立一个连接需要三次握手,而终止一个连接要经过四次握手,这是由TCP的半关闭(half-close)造成的,如图:

(1)客户端A发送一个FIN,用来关闭客户A到服务器B的数据传送(报文段4)。
(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。
(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A(报文段6)。
(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。

对应函数接口如图:

调用过程如下:

1) 当client想要关闭它与server之间的连接。client(某个应用进程)首先调用close主动关闭连接,这时TCP发送一个FIN M;client端处于FIN_WAIT1状态。

2) 当server端接收到FIN M之后,执行被动关闭。对这个FIN进行确认,返回给client ACK。

当server端返回给client ACK后,client处于FIN_WAIT2状态,server处于CLOSE_WAIT状态。它的接收也作为文件结束符传递给应用进程,因为FIN的接收 意味着应用进程在相应的连接上再也接收不到额外数据;

3) 一段时间之后,当server端检测到client端的关闭操作(read返回为0)。接收到文件结束符的server端调用close关闭它的socket。这导致server端的TCP也发送一个FIN N;此时server的状态为LAST_ACK。

4) 当client收到来自server的FIN后 。client端的套接字处于TIME_WAIT状态,它会向server端再发送一个ack确认,此时server端收到ack确认后,此套接字处于CLOSED状态。

这样每个方向上都有一个FIN和ACK。

1.为什么建立连接协议是三次握手,而关闭连接却是四次握手呢?

这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的连接请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;

但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。

2.为什么TIME_WAIT状态还需要等2MSL后才能返回到CLOSED状态?

这是因为虽然双方都同意关闭连接了,而且握手的4个报文也都协调和发送完毕,按理可以直接回到CLOSED状态(就好比从SYN_SEND状态到ESTABLISH状态那样):

一方面是可靠的实现TCP全双工连接的终止,也就是当最后的ACK丢失后,被动关闭端会重发FIN,因此主动关闭端需要维持状态信息,以允许它重新发送最终的ACK。

另一方面,但是因为我们必须要假想网络是不可靠的,你无法保证你最后发送的ACK报文会一定被对方收到,因此对方处于LAST_ACK状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT状态的作用就是用来重发可能丢失的ACK报文。

TCP在2MSL等待期间,定义这个连接(4元组)不能再使用,任何迟到的报文都会丢弃。设想如果没有2MSL的限制,恰好新到的连接正好满足原先的4元组,这时候连接就可能接收到网络上的延迟报文就可能干扰最新建立的连接。

3、发现系统存在大量TIME_WAIT状态的连接,可以通过调整内核参数解决:vi /etc/sysctl.conf 加入以下内容:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
然后执行 /sbin/sysctl -p 让参数生效。
net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭;
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭;
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。
net.ipv4.tcp_fin_timeout 修改系统默认的 TIMEOUT 时间


http://www.ppmy.cn/news/999935.html

相关文章

电磁兼容测试的条件与方法及要素

电磁骚扰源任何形式的自然或电能装置所发射的电磁能量,能使共享同一环境的人或其它生物受到伤害,或使其它设备、分系统或系统发生电磁危害,导致性能降低或失效,即称为电磁骚扰源,下面针对电磁兼容测试的条件与方法及要…

vue中人员导出功能实现

大纲: 1、导出定义的export.js文件 代码展示 import axios from axios //导出一 export const exportExcel (url, params, name, type post) > {// url url路径 params 查询参数 name 文件名 type 请求方式axios[type](url, params, {responseType: blob,}).t…

IC秋招| 秋招怎么做准备,这份攻略请收下!

近期大家关注的就是秋招了,如今一些企业已经开启了提前批招聘,不少同学已经投递了简历,但内心还是非常焦虑,那么今年的秋招到底该如何准备呢? 简历投递思路建议 刚开始对大厂没有把握的话,可以先约初创或…

【C语言】初识指针

【C语言】初识指针 一、指针是什么?二、指针和指针类型1. 指针-整数2. 指针的解引用三、野指针1.野指针成因2 .如何规避野指针四、指针运算五、二级指针七、指针数组 🎈个人主页:库库的里昂🎐CSDN新晋作者🎉欢迎 &…

当服务器域名出现解析错误的问题该怎么办?

​  域名解析是互联网用户接收他们正在寻找的域的地址的过程。更准确地说,域名解析是人们在浏览器中输入时使用的域名与网站IP地址之间的转换过程。您需要站点的 IP 地址才能知道它所在的位置并加载它。但,在这个过程中,可能会出现多种因素…

Vue3和typeScript路由传参

1 params传的参数,页面刷新就消失,而query传的参数,页面刷新还会存在,所以通常用query。 query传参 跳转页面:拿到router对象,调用push方法做跳转. import { useRoute,useRouter} from "vue-router"; export default…

K8s影响Pod调度和Deployment

5.应用升级回滚和弹性伸缩

【有趣的设计模式】23 种设计模式详解和场景分析

前言 七大设计原则 1、单一原则:一个类只负责一个职责 2、开闭原则:对修改关闭,对扩展开放 3、里氏替换原则:不要破坏继承关系 4、接口隔离原则:暴露最小接口,避免接口过于臃肿 5、依赖倒置原则&#xff1…