TIME_WAIT状态原理 CLOSE_WAIT状态原理 MSL RST

2016-12-23 21:00:00
admin
原创 3195
摘要:TIME_WAIT状态原理 CLOSE_WAIT状态原理 MSL RST

一、TIME_WAIT状态原理

1 什么是MSL?(windows一般2分钟,linux一般30秒)

MSL就是maximum segment lifetime(最大分节生命期,这是一个IP数据包能在互联网上生存的最长时间,超过这个时间IP数据包将在网络中消失。MSL在RFC 1122上建议是2分钟,而源自berkeley的TCP实现传统上使用30秒。


2 什么是RST?

RST标示复位,用来异常的关闭连接:
1.发送RST包关闭连接时,不必等缓冲区的包都发出去,直接就丢弃缓冲区中的包,发送RST。
2.而接收端收到RST包后,也不必发送ACK包来确认。

RST发送场景(有些黑客进行RST攻击):

1.端口未打开,服务端向客户端发送RST,有的OS也不发。

2.客户端在服务端关闭后仍然发送数据,服务端会发送RST。

3.超时,超时设置方发送。

4.提前关闭,数据没有收完就关闭连接。(关闭连接方发送,TCP是一种可靠的连接)

RST不发送场景:

1.使用shutdown、close关闭套接字,发送的是FIN,不是RST。
2.套接字关闭前,使用sleep。对运行的程序Ctrl+C,会发送FIN,不是RST。
3.套接字关闭前,执行return、exit(0)、exit(1),会发送FIN、不是RST。 


3 统计本地连接状态数量:

netstat -n | awk '/^tcp/{++S[$NF]} END{for(a in S) print a,S[a]}'


4 客户端主动关闭示例(close时fd内核计数为0才真正close,否则减计数,shutdown不检查内核计数,直接关闭):

通信双方建立TCP连接后,主动关闭连接的一方就会进入TIME_WAIT状态。客户端主动关闭连接时,发送最后一个ACK后进入TIME_WAIT状态,再停留2个MSL时间(后有MSL的解释,进入CLOSED状态。

1.客户端调用close()

2.服务端read()返回0

3.服务端调用close()


5 TIME_WAIT状态存在主要有两个原因(TIME_WAIT存活时间为2MSL):
可靠地实现TCP全双工连接的终止
TCP协议在关闭连接的四次握手过程中,最终的ACK是由主动关闭连接的一端(后面统称A端)发出的,如果这个ACK丢失,对方(后面统称B端)将重发出最终的FIN,因此A端必须维护状态信息(TIME_WAIT)允许它重发最终的ACK。如果A端不维持TIME_WAIT状态,而是处于CLOSED 状态,那么A端将响应RST分节,B端收到后将此分节解释成一个错误(java中会抛出connection reset的SocketException)。
因此要实现TCP全双工连接的正常终止,必须处理终止过程中四个分节任何一个分节的丢失情况,主动关闭连接的A端必须维持TIME_WAIT状态 。
允许老的重复分节在网络中消逝 
TCP分节可能由于路由器异常而“迷途”,在迷途期间,TCP发送端可能因确认超时而重发这个分节,迷途的分节在路由器修复后也会被送到最终目的地,这个迟到的迷途分节到达时可能会引起问题。在关闭“前一个连接”之后,马上又重新建立起一个相同的IP和端口之间的“新连接”,“前一个连接”的迷途重复分组在“前一个连接”终止后到达,而被“新连接”收到了。为了避免这个情况,TCP协议不允许处于TIME_WAIT状态的连接启动一个新的可用连接,因为TIME_WAIT状态持续2MSL,就可以保证当成功建立一个新TCP连接的时候,来自旧连接重复分节已经在网络中消逝。


6 TCP连接数据

客户端连接服务器时使用大于1024的空闲端口,linux一般最多6万,但压测时一般4000左右就会报address already in use异常。


7 如何使用TIME_WAIT的连接端口?

通过setsockopt设置SO_REUSEADDR连接选项。

SO_REUSEADDR三种使用场景:

1.复用处于TIME_WAIT状态的端口。

2.同一port绑定多个服务器实例,但ip不能相同。

3.允许完全相同的ip和port,只能用于UDP的多播。

    发表评论
    评论通过审核之后才会显示。