1.先来了解TCP四次挥手的过程:

①第一次:主机1(可以使客户端,也可以是服务器端),设置Sequence Number和Acknowledgment Number,向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;

②第二次:主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段,Acknowledgment Number为Sequence Number加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我“同意”你的关闭请求;

③第三次:主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入LAST_ACK状态;

④第四次:主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。

注:MSL是指Max Segment Lifetime,即数据包在网络中的最大生存时间。每种TCP协议的实现方法均要指定一个合适的MSL值,如RFC1122给出的建议值为2分钟,又如Berkeley体系的TCP实现通常选择30秒作为MSL值。这意味着TIME_WAIT的典型持续时间为1-4分钟。

2.TCP四次挥手过程中通信双方状态解析:

FIN_WAIT_1: 其实FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。而这两种状态的区别是:

FIN_WAIT_1状态实际上是当SOCKET在ESTABLISHED状态时,它想主动关闭连接,向对方发送了FIN报文,此时该SOCKET即进入到FIN_WAIT_1状态。而当对方回应ACK报文后,则进入到FIN_WAIT_2状态,当然在实际的正常情况下,无论对方何种情况下,都应该马上回应ACK报文,所以FIN_WAIT_1状态一般是比较难见到的,而FIN_WAIT_2状态还有时常常可以用netstat看到。(主动方)

FIN_WAIT_2:实际上FIN_WAIT_2状态下的SOCKET,表示半连接,也即有一方要求close连接,但另外还告诉对方,我暂时还有点数据需要传送给你(ACK信息),稍后再关闭连接。(主动方)

CLOSE_WAIT:表示在等待关闭。当对方close一个SOCKET后发送FIN报文给自己,你系统毫无疑问地会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,实际上你真正需要考虑的事情是察看你是否还有数据发送给对方,如果没有的话,那么你也就可以 close这个SOCKET,发送FIN报文给对方,也即关闭连接。所以你在CLOSE_WAIT状态下,需要完成的事情是等待你去关闭连接。(被动方)

LAST_ACK: 被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。当收到ACK报文后,也即可以进入到CLOSED可用状态了。(被动方)

TIME_WAIT: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN WAIT1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。(主动方)

CLOSED: 表示连接中断。

3.为什么要有TIME_WAIT这个状态?

假设最终的ACK丢失,主机2将重发FIN,主机1必须维护TCP状态信息以便可以重发最终的ACK,否则会发送RST,结果主机2认为发生错误。TCP实现必须可靠地终止连接的两个方向(全双工关闭),主机1必须进入 TIME_WAIT 状态,因为主机1可能面 临重发最终ACK的情形。

4.出现太多TIME_WAIT可能导致的后果:

在高并发短连接的TCP服务器上,当服务器处理完请求后立刻按照主动正常关闭连接。这个场景下,会出现大量socket处于TIMEWAIT状态。如果客户端的并发量持续很高,此时部分客户端就会显示连接不上。
我来解释下这个场景。主动正常关闭TCP连接,都会出现TIMEWAIT。为什么我们要关注这个高并发短连接呢?有两个方面需要注意:

① 高并发可以让服务器在短时间范围内同时占用大量端口,而端口有个0~65535的范围,并不是很多,刨除系统和其他服务要用的,剩下的就更少了。
 ②在这个场景中,短连接表示“业务处理+传输数据的时间 远远小于 TIMEWAIT超时的时间”的连接。这里有个相对长短的概念,比如,取一个web页面,1秒钟的http短连接处理完业务,在关闭连接之后,这个业务用过的端口会停留在TIMEWAIT状态几分钟,而这几分钟,其他HTTP请求来临的时候是无法占用此端口的。单用这个业务计算服务器的利用率会发现,服务器干正经事的时间和端口(资源)被挂着无法被使用的时间的比例是 1:几百,服务器资源严重浪费。(说个题外话,从这个意义出发来考虑服务器性能调优的话,长连接业务的服务就不需要考虑TIMEWAIT状态。同时,假如你对服务器业务场景非常熟悉,你会发现,在实际业务场景中,一般长连接对应的业务的并发量并不会很高)
     综合这两个方面,持续的到达一定量的高并发短连接,会使服务器因端口资源不足而拒绝为一部分客户服务。

5.time_wait状态如何避免

首先服务器可以设置SO_REUSEADDR套接字选项来通知内核,如果端口忙,但TCP连接位于TIME_WAIT状态时可以重用端口。在一个非常有用的场景就是,如果你的服务器程序停止后想立即重启,而新的套接字依旧希望使用同一端口,此时SO_REUSEADDR选项就可以避免TIME_WAIT状态。

time_wait状态产生的原因,危害,如何避免相关推荐

  1. TIME_WAIT状态产生的原因、过多的危害

    一.TCP连接断开的四次挥手: 由于TCP连接是全双工的,因此每个方向都必须单独进行关闭. 其原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接.收到一个 FIN只意味着这一方向 ...

  2. 【网络编程】time_wait状态产生的原因,危害,如何避免

    转自:https://blog.csdn.net/u013616945/article/details/77510925  做略微修改  仅供个人学习 1. time_wait状态如何产生? 在tcp ...

  3. TCP面试常见题:time_wait状态产生的原因,危害,如何避免

    http://blog.csdn.net/u013616945/article/details/77510925 MSL(Maximum Segment Lifetime)最大报文生存时间       ...

  4. TCP/IP详解--TIME_WAIT状态存在的原因

    1. 实际问题         初步查看发现,无法对外新建TCP连接时,线上服务器存在大量处于TIME_WAIT状态的TCP连接(最多的一次为单机10w+,其中引起报警的那个模块产生的TIME_WAI ...

  5. TIME_WAIT状态及存在原因

    1. 客户端与服务器端建立TCP/IP连接后关闭SOCKET后,服务器端连接的端口状态为TIME_WAIT:   2. 主动关闭的Socket端会进入TIME_WAIT状态,并且持续2MSL时间长度, ...

  6. 服务端大量处于TIME_WAIT和CLOSE_WAIT状态连接的原因

    服务端大量处于TIME_WAIT和CLOSE_WAIT状态连接的原因 1.服务端大量处于TIME_WAIT状态的连接原因? 1.HTTP没有使用长连接 2.HTTP长连接超时 3.HTTP长连接的请求 ...

  7. 服务端大量处于 time_wait和close_wait 状态连接的原因

    本片好文转自 Java灵风 https://www.toutiao.com/article/7176629612062327355/?app=news_article&timestamp=16 ...

  8. TIME_WAIT状态的原因及解决办法

    相关索引:https://blog.csdn.net/knowledgebao/article/details/84626184 目录 1,基础普及: 三次握手: 四次挥手 2,正文:那么服务端如何消 ...

  9. 网络:TCP通讯之 time_wait 状态

    基于TCP协议的通讯流程 1.TCP建立连接 2.TCP断开连接 3.TCP状态转换 TCP状态解释: SYN-RECVD:再收到和发送一个连接请求后等待对方对连接请求的确认 ESTABLISHED: ...

最新文章

  1. 轻松记账工程冲刺第二阶段10
  2. 大脚导入配置选择哪个文件_「科普向」为何我用大脚时,单体插件会安装失败?...
  3. 何时开始phonics学习及配套阅读训练zz
  4. python 添加类属性
  5. mysql8.0.17压缩包安装教程_超详细的MySQL8.0.17版本安装教程
  6. jvm类加载机制和类加载器_在JVM之下–类加载器
  7. 算法笔记_163:算法提高 最大乘积(Java)
  8. jsp中给div加背景_web前端入门到实战:详解css3如何给背景图片加颜色遮罩
  9. python的开发者是谁_谁才是真正的资深开发者?
  10. 每天一个linux命令(28):diff 命令
  11. 高级php程序员,php高级程序员该学什么
  12. 编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n。如果输入的是奇数调用1/1+1/3+...+1/n;...
  13. 安装运行jupyter notebook时报错:ModuleNotFoundError: No module named 'prompt_toolkit.formatted_text'...
  14. linux下类似Bus Hound的工具
  15. linux如何关闭oracle数据库,linux关闭oracle数据库命令
  16. Ubuntu更新Chrome到最新的版本
  17. 雷达原理---匹配滤波器原理及MATLAB仿真
  18. 内网win10安装flash插件
  19. 使用SpringBoot+RabbitMQ框架集成例程
  20. 关于Single Image Super Resolution(单幅影像超分辨率重建任务)Bicubic_LRX4影像生成的‘搬运‘想法

热门文章

  1. linux下如何查询jdk的安装路径
  2. angularjs ngRoute的使用简单例子
  3. 给GridView删除列添加删除提示
  4. C算法编程题(四)上三角
  5. Android JNI 编程
  6. 设为首页及收藏本页代码 兼容IE和Firefox
  7. NEO从源码分析看nep2与nep6
  8. cisco dhcp vlan vrrp ospf 实验
  9. EMC Isilon(OneFS)删除重要数据后恢复案例
  10. 3TB-GPT-MBR