面试题目整理 关于服务器TIME_WAIT和CLOSE_WAIT

本文深入解析TCP连接的三次握手和四次挥手过程,探讨正确连接关闭的方法,避免CLOSE_WAIT和TIME_WAIT状态的出现,并分析其背后的原因。

关于TCP 三次握手和四次挥手下面这个图已经很清晰了(盗图)

我之前用asio碰到过 大量连接 CLOSE_WAIT 状态

现在想想是没调用 socket_.shutdown(tcp::socket::shutdown::shutdown_both,ec);就直接析构了socket_

具体原因是客户端请求关闭连接的时候 服务器在收到 FIN M 之后 没发送 ack M+1 和 FIN N

正确的关闭连接是:

boost::system::error_code ec;

socket_.cancel(ec);

socket_.shutdown(tcp::socket::shutdown_both,ec);

socket_.close(ec);

而 TIME_WAIT状态出现在服务器接受了大量连接 主动关闭连接的时候(一般是web服务器)

这时候就要考虑是不是被攻击了

这里有篇文章讲解的比较详细

http://www.cnblogs.com/sunxucool/p/3449068.html

 

最近查看为什么会有三次握手和四次挥手的问题 找到一个很详细的解释

那么现在来回答为何连接建立是三次,而释放是四次呢。TCP连接其实是一个双向的连接,例如说,A与B两台电脑建立TCP连接时,实际A到B和B到A时看做两条通道的。在TCP连接建立的过程中,A向B发送连接请求,B需要发挥连接确认之后,这个时候其实连接已经建立了,但是为何还有A需要再次向B发送一个确认报文呢,因为网络不稳定,之前可能网络中会有很多失效的连接请求报文,如果没有确A再次确认的过程,那么如果有些失效报文又被重新受到,那么会影响当前的连接,因此是三次。这个时候,连接建立了,A与B可以相互通信。

连接释放的时候,实际上是其中一方,如A提出了释放请求,B收到后进行了报文确认,那么A到B的连接就释放了,这个时候,B还是可以向A发送数据,而且A会直接接收,到了B数据发送完了,B再向A发送请求释放的请求,B进入超时等待阶段,如果A及时发送连接中断确认,那么B就释放了B到A的连接,如果没有收到,超过一段时间,自动释放。

 

在操作系统中查看 TCP 连接状态(包括 `TIME_WAIT` `CLOSE_WAIT`)可以通过多种方式实现,具体方法取决于操作系统类型(如 Linux 或 Windows)以及是否使用命令行工具或编程接口。 ### Linux 系统中查看 TCP 连接状态 #### 1. 使用 `netstat` 命令 `netstat` 是一个常用的网络统计工具,可以显示当前的 TCP 连接状态。 - 查看所有 TCP 连接状态: ```bash netstat -ant ``` - 查看特定状态的连接(例如 `TIME_WAIT`): ```bash netstat -ant | grep TIME_WAIT ``` - 查看特定状态的连接(例如 `CLOSE_WAIT`): ```bash netstat -ant | grep CLOSE_WAIT ``` #### 2. 使用 `ss` 命令 `ss`(Socket Statistics)是一个更高效的工具,用于查看网络连接状态。 - 查看所有 TCP 连接状态: ```bash ss -ant ``` - 查看特定状态的连接(例如 `TIME_WAIT`): ```bash ss -ant 'state time-wait' ``` - 查看特定状态的连接(例如 `CLOSE_WAIT`): ```bash ss -ant 'state close-wait' ``` #### 3. 使用 `/proc/net/tcp` 文件 Linux 系统中可以通过读取 `/proc/net/tcp` 文件来获取 TCP 连接信息。 - 查看 `/proc/net/tcp` 文件内容: ```bash cat /proc/net/tcp ``` 文件中每一行代表一个 TCP 连接,其中 `st` 字段表示连接状态。例如: - `01`: `ESTABLISHED` - `05`: `CLOSE_WAIT` - `06`: `LAST_ACK` - `07`: `TIME_WAIT` #### 4. 使用 Python 脚本获取 TCP 连接状态 通过 Python 的 `psutil` 库可以编程获取 TCP 连接状态。 ```python import psutil # 获取所有 TCP 连接 connections = psutil.net_connections() # 过滤出 TIME_WAIT CLOSE_WAIT 状态的连接 for conn in connections: if conn.status == 'TIME_WAIT' or conn.status == 'CLOSE_WAIT': print(conn) ``` ### Windows 系统中查看 TCP 连接状态 #### 1. 使用 `netstat` 命令 Windows 系统也支持 `netstat` 命令。 - 查看所有 TCP 连接状态: ```cmd netstat -an ``` - 查看特定状态的连接(例如 `TIME_WAIT`): ```cmd netstat -an | findstr TIME_WAIT ``` - 查看特定状态的连接(例如 `CLOSE_WAIT`): ```cmd netstat -an | findstr CLOSE_WAIT ``` #### 2. 使用 PowerShell 脚本 PowerShell 提供了更强大的功能,可以通过脚本获取 TCP 连接状态。 - 获取所有 TCP 连接: ```powershell Get-NetTCPConnection ``` - 过滤出 `TIME_WAIT` 状态的连接: ```powershell Get-NetTCPConnection | Where-Object { $_.State -eq "TimeWait" } ``` - 过滤出 `CLOSE_WAIT` 状态的连接: ```powershell Get-NetTCPConnection | Where-Object { $_.State -eq "CloseWait" } ``` ### 查看系统中 `TIME_WAIT` `CLOSE_WAIT` 的数量 #### Linux 系统 - 查看 `TIME_WAIT` 连接数量: ```bash ss -ant 'state time-wait' | wc -l ``` - 查看 `CLOSE_WAIT` 连接数量: ```bash ss -ant 'state close-wait' | wc -l ``` #### Windows 系统 - 查看 `TIME_WAIT` 连接数量: ```cmd netstat -an | findstr TIME_WAIT | find /c /v "" ``` - 查看 `CLOSE_WAIT` 连接数量: ```cmd netstat -an | findstr CLOSE_WAIT | find /c /v "" ``` ### 总结 通过上述方法,可以有效地在 Linux Windows 系统中查看 TCP 连接状态,尤其是 `TIME_WAIT` `CLOSE_WAIT` 状态的连接。这些工具脚本可以帮助快速诊断网络问题,并优化系统性能[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值