网络中的TIME-WAIT和CLOSE-WAIT


在这里插入图片描述

1、主动关闭方发送FIN包,进入FIN-WAIT1状态

2.1、被动关闭方收到FIN包后,回复ACK包,进入CLOSE_WAIT状态

2.2、主动关闭方收到ACK包后,等待对方关闭,进入FIN_WAIT2状态

3、被动关闭方在完成所有数据发送后,调用close()操作;此时,协议层发送FIN包给主动关闭方,等待对方的ACK,被动关闭的一方进入LAST_ACK状态;

4、主动关闭方收到FIN包,协议层回复ACK;此时,主动关闭方,进入TIME_WAIT状态;而被动关闭方收到ACK后,进入CLOSED状态 ;

5、主动关闭方等待2MSL(max segment lifetime)时间后,结束TIME_WAIT,进入CLOSED状态 ;

这里有个问题,就是主动关闭方发送最后一个ACK包后,为什么要进入TIME-WAIT等待2MSL而不是进入CLOSED状态,2MSL是一个发送加一个回复的最大时间,如果直到2MSL后主动关闭方没有再次收到FIN,那么可以推断出ACK已被成功接收,结束TCP连接。

而主动关闭方为什么会在发出ACK后又收到FIN包,这是因为被动关闭方在发出最后一个ACK包后也会等待2MSL的时间,如果在这个时间内没有收到主动关闭方回复的ACK后,可能是由于被动关闭方发送的FIN包没有被收到,也可能是主动关闭方回复的ACK包由于网络等原因没有发送成功,此时被动关闭方会再次发送一个FIN包给主动关闭方。

TIME_WAIT有什么用?

TIME_WAIT的出现,是为了解决网络的丢包和网络不稳定所带来的其他问题

1)**防止前一个连接上延迟的数据包或者丢失重传的数据包,被后面复用的连接错误地接收。**如果没有TIME_WAIT,或者TIME_WAIT时间非常端,那么连接关闭后源端口可能马上被服用,此时,前面一个连接上的数据被后面的一个连接错误的接收。

2)确保连接方能在时间范围内,关闭自己的连接。 如果主动关闭的一方回复的最后一个ACK丢失,而被动关闭的一方还继续停留在LAST_ACK状态,如果没有TIME_WAIT的存在,或者说,停留在TIME_WAIT上的时间很短,则主动关闭的一方很快就进入了CLOSED状态,也即是说,如果此时新建一个连接,源随机端口如果被复用,在新连接上发送SYN包后,由于被动方仍认为这条原先的连接还在等待ACK,但是却收到了SYN,则被动方会回复RST,造成新建立的连接无法成功。

服务器异常解决方案

如果服务器出了异常,百分之八九十都是下面两种情况:

1.服务器保持了大量TIME_WAIT状态

基于TCP的HTTP协议,关闭连接的不是客户端,而是服务器,所以web服务器也是会出现大量的TIME_WAIT的情况的。解决思路就是让服务器能够快速回收和重用那些TIME_WAIT的资源,可以修改对应的配置文件。

/etc/sysctl.conf

  1. #对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃,不应该大于255,默认值是5,对应于180秒左右时间
  2. net.ipv4.tcp_syn_retries=2
  3. #net.ipv4.tcp_synack_retries=2
  4. #表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为300秒
  5. net.ipv4.tcp_keepalive_time=1200
  6. net.ipv4.tcp_orphan_retries=3
  7. #表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间
  8. net.ipv4.tcp_fin_timeout=30
  9. #表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
  10. net.ipv4.tcp_max_syn_backlog = 4096
  11. #表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭
  12. net.ipv4.tcp_syncookies = 1
  13. #表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭
  14. net.ipv4.tcp_tw_reuse = 1
  15. #表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭
  16. net.ipv4.tcp_tw_recycle = 1
  17. ##减少超时前的探测次数
  18. net.ipv4.tcp_keepalive_probes=5
  19. ##优化网络设备接收队列
  20. net.core.netdev_max_backlog=3000
2.服务器保持了大量CLOSE_WAIT状态

TIME_WAIT状态可以通过优化服务器参数得到解决,因为发生TIME_WAIT的情况是服务器自己可控的,要么就是对方连接的异常,要么就是自己没有迅速回收资源,总之不是由于自己程序错误导致的。

但 是CLOSE_WAIT就不一样了,如果一直保持在CLOSE_WAIT状态,那么只有一种情况,就是在对方连接关闭之后,程序里没有检测到,或者程序压根就忘记了这个时候需要关闭连接,于是这个资源就一直被程序占着。所以解决方法只能是检查代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值