socket close和shutdown的区别,TIME_WAIT和CLOSE_WAIT
TCP主动关闭连接
appl: close(), --> FIN FIN_WAIT_1 //主动关闭socket方,调用close关闭socket,发FIN
<-- ACK FIN_WAIT_2 //对方操作系统的TCP层,给ACK响应。然后给FIN
<-- FIN
--> ACK "TIME_WAIT" -- 2MSL timeout -->CLOSED //TIME_WAIT,防止ACK没有给到对方。
TCP被动关闭连接
<-- FIN "CLOSE_WAIT" //被动方,收到对方的FIN,处于CLOSE_WAIT状态
--> ACK //被动方的TCP层,给ACK响应
app2: close(), --> FIN LAST_ACK //被动方调用close,从CLOSE_WAIT转到LAST_ACK 不调close,将一直在CLOSE_WAIT状态。
<-- ACK --> CLOSED tcp是全双工:: 因此close()关闭读写。 shutdown()可以选择关闭读或写。 time_wait的时间会非常长,因此server尽量减少主动关闭连接。
int close(int sockfd); int shutdown(int sockfd, int howto); // howto: SHUT_RD, SHUT_WR, SHUT_RDWR
shutdown()函数的两个作用:
close()将描述字的引用计数减1,当引用计数为0时,才关闭socket。
如fork()模式中,父进程在accept()返回后,fork()子进程,由子进程处理connfd,而父进程将close(connfd);但此时父进程的close()并不引发FIN。
shutdown()则不管socket的引用计数,直接发生FIN。
shutdown()可控制read/write两个方向的管道。
SHUT_RD shutdown(sockfd, SHUT_RD);后,来自对端的数据都被确认,然后悄然丢弃。 SHUT_WR half close状态。
close()引发的4次交互:(这里的close是client发起的)
client server
FIN_WAIT_1 ---- FIN M ------> (Server端操作系统的TCP层响应ACK包)
<---- ACK M+1---- CLOSE_WAIT FIN_WAIT_2 (这里必须调用close,才能从CLOSE_WAIT到LAST_ACK)
<------ FIN N ----- LAST_ACK TIME_WAIT (TIME_WAIT有一个重要的作用就是防止最后一个ACK丢失)
------- ACK N+1 ----------> CLOSE
TIME_WAIT 是主动关闭链接时形成的,等待2MSL时间,约4分钟。
主要是防止最后一个ACK丢失。 由于time_wait的时间会非常长,因此server端应尽量减少主动关闭连接
CLOSE_WAIT是被动关闭链接是形成的 ,
按状态机,我方收到FIN,则由TCP实现发送ACK,因此进入CLOSE_WAIT状态。
但如果我方不执行close(),就不能由CLOSE_WAIT迁移到LAST_ACK,则系统中会存在很多CLOSE_WAIT状态的连接。
此时,可能是系统忙于处理读、写操作,而未将已收到FIN的连接,进行close。此时,recv/read已收到FIN的连接socket,会返回0。
大量TIME_WAIT和CLOSE_WAIT的存在,会产生怎样的影响?
内核维护更多的状态。收到ip包,做hash运算,hlist冲突的概率更大。
1. 首先明确下什么是2MSL: TCP四次挥手断开连接时,主动断开连接的一方(这里我们称为客户端A)在收到对端(这里我们称为服务端B)发送的FIN包后,会立马发送ACK响应包并等待一段时间以确保自己发送的ACK包能够成功通过网络传输到达服务端B端,从而帮助B端正常断开连接(B服务端只有收到自己发出的FIN包对应的ACK包后,才能正常释放资源断开连接),这一等待时间的时长为2MSL,是从客户端A发出ACK包开始计算的,如果A在发送完ACK包后又收到了B端发送的新的FIN包,则会再次发送新的ACK包并重新计时(B端可能会因为超时或丢包等各种原因重新发送FIN包);
2. 其次明确下什么是MSL:MSL 即 Maximum Segment Lifetime,它是任何 TCP segment 在网络上存在的最长时间,超过这个时间的 TCP 报文就会被丢弃,RFC793定义了MSL为2分钟,但这完全是从工程上来考虑的,对于现在的网络,不同操作系统的TCP实现,可以根据具体网络情况配置使用更小的MSL;
3. 再次明确下为什么TCP第四次挥手需要等待2MSL:客户端A等待2MSL可以确保客户端A和服务端B之间的数据包可以完成一个完整的来回的传输即 round trip,所以如果A先前发送的ACK包因为某些原因在网络上丢失了,服务端B在超时没有收到客户端A的ACK包后会重新发送FIN包,2MSL的等待时间能够确保客户端A收到服务端B发送的新的FIN包以发送新的ACK包并重新计时;
4. 最后说下如何在LINUX操作系统中查看和配置MSL: 其实在LINUX操作系统中并没有直接配置 MSL 而是配置了 tcp_fin_timeout,由于 tcp_fin_timeout=2MSL,所以我们可以查看tcp_fin_timeout并据此推断MSL: 可以通过命令 sysctl net.ipv4.tcp_fin_timeout 查看 tcp_fin_timeout,可以通过命令 sysctl -w net.ipv4.tcp_fin_timeout=30 修改 tcp_fin_timeout;
简单概括下,因为网络是不可靠的,数据包在传输过程中可能丢失可能超时可能乱序,所以TCP为了在逻辑的虚拟的连接的基础上提供可靠性,在四次挥手断开连接时主动断开连接的一方需要2MSL的等待时间(当然三次握手和四次挥手,以及连接过程中的确认/累计确认/选择确认等机制,也都是这个原因)
TCP四次挥手也遵循相似的套路。
主动断开的一侧为A,被动断开的一侧为B。
第一个消息:A发FIN
第二个消息:B回复ACK
第三个消息:B发出FIN
此时此刻:B单方面认为自己与A达成了共识,即双方都同意关闭连接。
此时,B能释放这个TCP连接占用的内存资源吗?不能,B一定要确保A收到自己的ACK、FIN。
所以B需要静静地等待A的第四个消息的到来:
第四个消息:A发出ACK,用于确认收到B的FIN
当B接收到此消息,即认为双方达成了同步:双方都知道连接可以释放了,此时B可以安全地释放此TCP连接所占用的内存资源、端口号。
所以被动关闭的B无需任何wait time,直接释放资源。
但,A并不知道B是否接到自己的ACK,A是这么想的:
1)如果B没有收到自己的ACK,会超时重传FiN
那么A再次接到重传的FIN,会再次发送ACK
2)如果B收到自己的ACK,也不会再发任何消息,包括ACK
无论是1还是2,A都需要等待,要取这两种情况等待时间的最大值,以应对最坏的情况发生,这个最坏情况是:
去向ACK消息最大存活时间(MSL) + 来向FIN消息的最大存活时间(MSL)。
这恰恰就是2MSL( Maximum Segment Life)。
等待2MSL时间,A就可以放心地释放TCP占用的资源、端口号,此时可以使用该端口号连接任何服务器。
为何一定要等2MSL?
如果不等,释放的端口可能会重连刚断开的服务器端口,这样依然存活在网络里的老的TCP报文可能与新TCP连接报文冲突,造成数据冲突,
为避免此种情况,需要耐心等待网络老的TCP连接的活跃报文全部死翘翘,2MSL时间可以满足这个需求(尽管非常保守)!
socket close和shutdown的区别,TIME_WAIT和CLOSE_WAIT的更多相关文章
- socket链接的关闭连接与close和shutdown的区别
TCP主动关闭连接 appl: close(), --> FIN FIN_WAIT_1 //主动关闭socket方,调用close关闭socket,发FIN <-- ACK FIN_WAI ...
- socket 编程 : shutdown vs close
TCP/IP 四次挥手 首先作者先描述一下TCP/IP 协议中四次挥手的过程,如果对此已经熟悉的读者可以跳过本节. 四次挥手 这是一个很经典的示例图,众所周知tcp socket 在一个生命周期中有很 ...
- TIME_WAIT和CLOSE_WAIT状态区别
[TIME_WAIT和CLOSE_WAIT状态区别] 常用的三个状态是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主动关闭,CLOSE_WAIT 表示被动关闭. TCP协议规定,对 ...
- linux reboot ,shutdown,halt区别
reboot ,shutdown,halt区别 重启 reboot 和 shutdown -r now 效果是一样的都是重启 区别在于reboot 是重启时,删除所有的进程,为不是平稳的终止他 ...
- TIME_WAIT和CLOSE_WAIT的区别
系统上线之后,通过如下语句查看服务器时,发现有不少TIME_WAIT和CLOSE_WAIT. netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) ...
- 服务器TIME_WAIT和CLOSE_WAIT区别及解决方案
系统上线之后,通过如下语句查看服务器时,发现有不少TIME_WAIT和CLOSE_WAIT. netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) ...
- TCP连接(Time_Wait、Close_Wait)说明
修改Time_Wait和CLOSE_WAIT时间 修改Time_Wait参数的方法 (在服务端修改)Windows下在HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlS ...
- TCP连接的TIME_WAIT和CLOSE_WAIT 状态解说【转】
相信很多运维工程师遇到过这样一个情形: 用户反馈网站访问巨慢, 网络延迟等问题, 然后就迫切地登录服务器,终端输入命令"netstat -anp | grep TIME_WAIT | wc ...
- 一次TIME_WAIT和CLOSE_WAIT故障和解决办法
昨天解决了一个curl调用错误导致的服务器异常,具体过程如下: 里头的分析过程有提到,通过查看服务器网络状态检测到服务器有大量的CLOSE_WAIT的状态. 在服务器的日常维护过程中,会经常用到下面的 ...
- TCP之 TIME_WAIT和CLOSE_WAIT 状态 的原因分析和处理
转自:http://blog.csdn.net/shootyou/article/details/6622226 昨天解决了一个HttpClient调用错误导致的服务器异常,具体过程如下: http: ...
随机推荐
- P6680 [CCO2019] Marshmallow Molecules 题解
P6680 题意 一个 \(n\) 点 \(m\) 边的图,图无重边,无自环. 满足这样一条性质:如果三边互不相等,则三边可以构成三角形. 思路 思路简单,用集合的思想来做. 引用一下 K0stlin ...
- 手把手教你!STM32单片机入门指南:从初级到中级工程师的学习路线
在当今科技日新月异的时代,嵌入式系统作为智能设备的核心驱动力,正以前所未有的速度渗透到我们生活的方方面面.STM32系列微控制器,以其高性能.低功耗及丰富的外设资源,成了许多开发者踏入嵌入式领域首选 ...
- DSCL:已开源,北京大学提出解耦对比损失 | AAAI 2024
监督对比损失(SCL)在视觉表征学习中很流行.但在长尾识别场景中,由于每类样本数量不平衡,对两类正样本进行同等对待会导致类内距离的优化出现偏差.此外,SCL忽略了负样本之间的相似关系的语义线索.为了提 ...
- linux一行执行多条命令 shell
要实现在一行执行多条Linux命令,分三种情况: 1.&& 举例: lpr /tmp/t2 && rm /tmp/t2 第2条命令只有在第1条命令成功执行之后才执行.当 ...
- 通过Jupyter Notebook+OpenAI+ollama简单的调用本地模型
通过Jupyter Notebook+OpenAI+ollama简单的调用本地模型 起因是收到了ollama的邮件,貌似支持使用openai来调用本地的ollama下载的模型为自己用 想了下正好试下, ...
- vue-puzzle-vcode与vue-drag-verify纯前端的拼图人机验证、右滑拼图验证
转载作品!以获取原作者允许,原文地址,感觉写的比较全面,也比较实用,大家可以去看看原文章: 纯前端的拼图人机验证.右滑拼图验证 1.vue-puzzle-vcode github地址:https:// ...
- 【Hearts Of Iron IV】钢铁雄心4 安装笔记
一.解决Steam购买游戏和下载问题 我可能是正版受害者 Steam平台这个游戏本体是购买锁国区的 然后在淘宝上面买激活码激活的 都激活过了的Key,所以放出来也无所谓了 钢铁雄心4学员版本体:7B0 ...
- 【Tutorial C】02 快速入门
在信息化.智能化的世界里,可能很早很早 我们就听过许多IT类的名词, C语言也在其中,我们侃侃而谈,到底C程序是什么样子? 让我们先看简单的一个例子: #include<stdio.h> ...
- 【Windows】开放共享目录
在项目里面做数据迁移时发现,WindowsServer的多个主机可以进行磁盘共享访问 但是自己设置是灰白无法点击的 文件目录共享还是可以进行设置的 1.找到自己需要共享的目录,右键选择[属性],并找到 ...
- 【Dos-BatchPrograming】03
--1.AT 计划任务 Microsoft Windows [版本 10.0.19041.746] (c) 2020 Microsoft Corporation. 保留所有权利. C:\Users\A ...