TIME_WAIT状态原理 CLOSE_WAIT状态原理
- 2015-08-15 21:00:00
- admin
- 原创 3442
一、TIME_WAIT状态原理
本地连接状态数量:
netstat -n | awk '/^tcp/{++S[$NF]} END{for(a in S) print a,S[a]}'
什么是MSL?
MSL,Maximum Segment Lifetime,最大报文存活时间,这是一个IP数据包能在互联网上生存的最长时间,超过这个时间数据包将在网络中消失。RFC建议是2分钟,Windows采用,Berkeley的TCP实现传统上使用30秒,Linux采用。
什么是RST?
RST表示复位,用来关闭异常的连接:
1、发送RST关闭连接时,直接丢弃缓冲区的包;
2、接收端收到RST,也不必发送ACK来确认;
RST发送场景,有些黑客进行RST攻击:
1、端口未打开,服务端向客户端发送RST,有些操作系统不发;
2、客户端在服务端关闭后仍然发送数据,服务端会发送RST;
3、提前关闭,数据没有收完就关闭连接,关闭连接方发送;
4、超时,超时设置方发送给对端;
RST不发送场景:
1、使用shutdown、close关闭套接字,发送FIN,不是RST;
2、套接字关闭前,调用sleep,对程序Ctrl+C,会发送FIN,不是RST;
3、套接字关闭前,调用return、exit(0)、exit(1),会发送FIN,不是RST;
客户端主动关闭示例:
通信双方建立TCP连接后,主动关闭连接的一方进入TIME_WAIT状态。客户端主动关闭连接时,发送ACK后进入TIME_WAIT状态,停留两个MSL时间,进入CLOSED状态。close时fd内核计数为零才关闭,否则减计数,shutdown不检查内核计数,直接关闭。
TIME_WAIT存活两个MSL主要原因:
可靠地实现TCP全双工连接的终止
TCP协议在关闭连接的四次握手过程中,最终的ACK由主动关闭连接的一方A端发出,如果这个ACK丢失,对方B端将重发最终的FIN,因此A端必须维护状态信息TIME_WAIT,允许它重发最终的ACK,如果A端不维持TIME_WAIT状态,而是处于CLOSED状态,那么A端将响应RST,B端收到后将会解释为错误。因此要实现TCP全双工连接的正常终止,必须处理终止过程中四个分节任何一个分节的丢失情况,主动关闭连接的A端必须维持TIME_WAIT状态。
允许老的重复分节在网络中消逝
TCP分节可能由于路由器异常而迷途,在迷途期间,TCP发送端可能因超时而重发这个分节,迷途的分节在路由器修复后也会被送到最终目的,这个迟到的迷途分节可能会引起问题。在关闭前一个连接后,马上重新建立一个相同的IP和端口之间的新连接,前一个连接的迷途分组可能被新连接收到。为了避免这个情况,TCP协议不允许处于TIME_WAIT状态的连接启动一个新的可用连接,因此TIME_WAIT状态持续两MSL,可以保证当成功建立一个新TCP连接时,来自旧连接重复分节已经在网络中消逝。
如何使用TIME_WAIT的连接端口?
1、客户端连接服务端时,使用大于1024的端口,Linux一般最多6万;
2、压测时,一般4000左右就会报异常address already in use;
3、setsockopt设置SO_REUSEADDR复用地址;
SO_REUSEADDR使用场景:
1、复用处于TIME_WAIT状态的端口;
2、同一端口绑定多个服务,IP不能相同;
3、完全相同的地址,只能用于UDP多播;