聊聊TCP四次挥手中的timewait

来源:互联网 发布:mac六国循环重启 恢复 编辑:程序博客网 时间:2024/06/02 04:01

一句话总结:保证双方正常关闭、废弃存在于路由上的旧信息。

下面假设A是主动关闭方,B是被动关闭方。

1、time wait什么时候出现

当A主动关闭发送FIN给B时,进入FIN_WAIT_1,

B接收到FIN后发给A一个ACK,进入CLOSE_WAIT

当A接收到B的ACK后进入FIN_WAIT_2

B进入CLOSE_WAIT后没有数据发送,则发送FIN,进入LAST_ACK

A接收到B的FIN后进入TIME_WAIT,发送ACK

B接收到A的ACK后关闭,A等待2MSL后关闭。

2、为何需要timewait这个状态

(1)A不能保证最后的ACK能到达B,如果丢失了,B收不到会重发FIN,timewait状态的存在可以让A重发ACK来在一定程度上保证TCP连接正常关闭。

(2)当一个TCP连接关闭后,重新又被用到,有了timewait可以在一定程度上丢弃掉之前无用的网络包。通用经验是将TIMEWAIT定义为2MSL,无法从理论上百分百保证。

3、去掉timewait这个状态行不行

(1)如果去掉,从1中的流程可以看出,在最后一次握手中,A接收到B的FIN后发送完ACK就关闭了,如果B没有接收到ACK,则会重发FIN,而此时A已经关闭了,会给B发送一个RST,此时B接收到RST后报错。

(2)如果去掉TIMEWAIT,假设TCP连接正常关闭了,接着在1MSL内又重新用到了该TCP连接,那么之前存在于路由上的旧网络包可能被重新接收到。

4、如何避免time_wait状态占用资源

客户端一般是临时端口,不太担心资源问题

服务端由于端口是指定的,处于time_wait时不能使用,会一定程度上造成资源浪费,可以用setsockopt函数中的选项SO_REUSEADDR设置重用即可。

可以通过内核参数改变time_wait的时间长度甚至关闭不让其进入time_wait状态,当然这是不建议的。

原创粉丝点击