"挥手是为了终止TCP连接"
代码语言:javascript复制```
TCP采用四次挥手来释放连接
第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态;
第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号 1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态;
第三次挥手:Server 发送一个FIN,用来关闭 Server到Client的数据传送,Server 进入LAST_ACK状态;
第四次挥手:Client收到FIN后,Client 进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号 1,Server 进入CLOSED状态,完成四次挥手。
```
为什么会有TIME_WAIT状态
原因&作用
- 确保有足够的时间让对方收到ACK包(如果在这个时间之内,对面说没收到,我们这边都可以进行重传)
- 避免新旧连接混淆
为什么需要四次挥手才能断开连接
因为TCP连接是全双工(双方都有发送数据和接收数据功能),发送方和接收方都需要FIN报文和ACK报文
有人会说,为什么不像三次握手一样,把第二次挥手和第三次挥手放在一起,我认为这个原因是因为,通常情况下,我们建立连接不需要准备什么,而我们在做断开连接时候,需要一定时间确认自己现在任务已经完成,所以接收方需要当自己任务完成时候再另外发送一个FIN断开信号.
服务器出现大量CLOSE_WAIT状态的原因
对方关闭socket连接,我方忙于读或写,没有及时关闭连接 解决方案
- 检查代码,特别是释放资源的代码
- 检查配置,特别是处理请求的线程配置
为什么四次挥手要有2MSL的 TIME WAIT的时间?
概念:MSL是报文在网络中最长生存时间,这是一个工程值(经验值),不同的系统中可能不同。 场景:1. A发出ACK后,等待一段时间T,确保如果B重传FIN自己一定能收到 分析:
- ACK从A到B最多经过1MSL,超过这个时间B会重发FIN
- B重发的FIN最多经过1MSL到达A结论:如果B重发了FIN,且网络没有故障(重发的FIN被丢弃或错误转发),那么A一定能在2MSL之内收到该FIN,因此A只需要等待2MSL。 总结:确保A可以收到B的FIN进行正常的关闭.
另外等待 2MSL 可以避免
前后两个使用相同四元组的连接中的前一个连接的报文干扰后一个连接
,换句话说,就是为了让此次 TCP 连接中的所有报文在网络中消失.
详细可以看