先上转换图:

  重点研究TIME_WAIT状态,根据UNIX网络编程中的思路,TIME_WAIT状态有两个存在的理由:

理由1、

  客户端执行主动关闭,假设最终的ACK丢失,服务器将重新发送它的最后那个FIN,因此客户端必须维护状态信息,以允许它重新发送最终那个ACK,要是客户端 不维护状态信息,它将响应一个RST分节,该分节将被服务器解释成一个错误,如果TCP打算执行所有必要的工作以彻底终止连接上两个方向的数据流,那么它必须正确处理连接终止序列4个分节中任何一个分节丢失的情况。为什么执行主动关闭的那一端是处于TIME_WAIT状态的那一端:因为可能不得不重传最终那个ACK的就是那一端。

  看了理由1的解释,想必还是有点蒙,根据个人的理解,给出一个通俗的解释:

  MSL是最长分节生命期,也即一个分节在网络中传输,如果经过MSL时间还没有到达目的地,则这个分节自动失效。TIME_WAIT状态的超时时间是2MSL,就是如果TCP处于TIME_WAIT状态时,经过2MSL的时间后悔自动转到CLOSED状态。如果在TIME_WAIT状态时收到服务器发来的FIN,则会回复一个ACK。从图中可以看到,正常情况下,是从FIN_WAIT_2状态回复ACK然后转到TIME_WAIT状态的。而在TIME_WAIT状态恢复ACK则会转到CLOSED状态,不用等到超时时间到。

  要是客户端不维护状态信息,也即没有TIME_WAIT状态,则客户端在FIN_WAIT_2状态回复ACK后直接回到CLOSED状态,来看看这样会存在什么问题,如果客户端在FIN_WAIT_2状态回复的这个ACK丢失了,而服务器由于超时没有接到ACK则会再一次发送FIN给客户端,这时的客户端是处于CLOSED状态的,当它接到FIN后会回复一个RST,服务器如果接到了这个RST则会解释成一个错误,这明显不是我们期望的。因此,客户端维护一个TIME_WAIT状态也就是有必要的了,在TIME_WAIT状态时收到FIN并回复ACK,然后回到CLOSED状态,这样客户端就功成身退了。读到这里,可能有读者会迷惑,如果在TIME_WAIT状态回复的这个ACK再次丢失呢,那处于CLOSED状态的客户端不还是会再次接收到服务端发来的FIN,然后回复RST吗?我想说不会的,这个ACK即使再丢失,服务端也不会回复FIN的,处于CLOSED状态的客户端也就不会再接收到FIN。要不然,在网络不稳定的情况下,客户端和服务器会陷入死循环,永远无法走出困境。看下面的分析。

  解释一下为什么客户端的TIME_WAIT状态的超时时间是2MSL? 假设0时刻,客户端接收到服务端的第一次FIN,并回复ACK,进入TIME_WAIT状态。经过MSL时间,服务端没有收到这个ACK,判定超时,因此,再次发送FIN给客户端(正常情况下,服务器在CLOSE_WAIT状态第一次发送FIN,然后进入LAST_ACK状态,如果没有成功接收到客户端的ACK,则第一次超时后再次发送FIN,这次是从LAST_ACK开始的,发送完FIN后继续留在LAST_ACK状态,如果这次再超时便转入CLOSED状态,因此,以后就不会再发送FIN了,这正好解释了上面的红色部分),这个FIN的存活期最多也为MSL,如果在MSL时间内成功到达客户端,则客户端这时还处于TIME_WAIT状态,可以正确处理这个FIN,如果这个FIN在MSL时间内没有到达客户端,则自动失效,客户端也进入CLOSED状态,功成身退。

  假如设计者让客户端处于TIME_WAIT状态的超时时间小于2MSL的话,我们再从头分析一次,0时刻,客户端接收到服务端的第一次FIN,并回复ACK,进入TIME_WAIT状态。经过MSL时间,服务端没有收到这个ACK,判定超时,因此,再次发送FIN给客户端,这个FIN存活期最多为MSL,如果FIN在MSL时间的最后一刻到达客户端,由于TIME_WAIT状态的超时时间小于2MSL,客户端已经回到了CLOSED状态,在CLOSED状态接收到FIN必然会回复RST,这是我们不希望的。因此,TIME_WAIT状态的超时时间要大于等于2MSL。

理由2:

  我们假设在12.106.32.254的1500端口和206.168.112.219的21端口之间有一个TCP连接,我们关闭这个连接,过一段时间后,我们在相同的IP地址和端口之间建立另一个连接,后一个连接称为前一个连接的化身,因为他们的IP地址和端口号都相同,如果不存在TIME_WAIT状态的话,这个连接可以成功建立,而此时可能还有上一个连接的分节在网络中传输,还没有超过MSL时间而死掉。在相同的IP地址和端口上的新连接建立好之后,可能有一端会收到这个分节,这时我们不期望的。因此,设置了TIME_WAIT状态,TCP协议栈不会给处于TIME_WAIT状态的IP和端口建立连接,而直到超时2MSL时间退出TIME_WAIT状态后才可以建立新连接,这时网络中的相同IP和端口上的旧连接中的分节也早就死了。

TCP状态转化图 TIME_WAIT解析的更多相关文章

  1. TCP建立连接和释放的过程,及TCP状态变迁图

    一.TCP报文格式 下面是TCP报文格式图: 重要字段介绍: (1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记. (2)确认序号:Ack序号,占 ...

  2. Linux记录-TCP状态以及(TIME_WAIT/CLOSE_WAIT)分析(转载)

    1.TCP握手定理 2.TCP状态 l  CLOSED:初始状态,表示TCP连接是“关闭着的”或“未打开的”. l  LISTEN :表示服务器端的某个SOCKET处于监听状态,可以接受客户端的连接. ...

  3. TCP状态变迁图

    服务端,端口的状态变化 先在本机(IP地址为:192.168.1.10)配置FTP服务,然后在其它计算机(IP地址为:192.168.1.1)访问FTP服务,从TCPView看看端口的状态变化. 下面 ...

  4. TCP/IP详解--连接状态变迁图CLOSE_WAIT

    终止一个连接要经过4次握手.这由TCP的半关闭(half-close)造成的.既然一个TCP连接是全双工(即数据在两个方向上能同时传递,可理解为两个方向相反的独立通道),因此每个方向必须单独地进行关闭 ...

  5. TCP状态转换图解析

    本文参考Unix网络编程卷1,对TCP状态转换进行总结,方便掌握TCP链接中各个状态及故障分析. 1.Linux下TCP相关工具 基于Linux系统查看网络状态,首先了解几个基本查看指令. Linux ...

  6. tcp连接的状态变迁以及如何调整tcp连接中处于time_wait的时间

    一.状态变迁图 二.time_wait状态 针对time_wait和close_wait有个简单的描述帮助理解: Due to the way TCP/IP works, connections ca ...

  7. TCP三次握手,四次挥手,状态变迁图

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  8. tcp状态-TIME_WAIT与CLOSE_WAIT带来的坑

    tcp状态: http://www.cnblogs.com/DengGao/p/tcp_state.html 1. tcp连接会占用系统资源(文件描述符), 有时候甚至会导致系统假死(不能发起或者处理 ...

  9. 关于TCP状态TIME_WAIT的理解

    1.TIME_WAIT的作用: TIME_WAIT状态存在的理由:1)可靠地实现TCP全双工连接的终止 在进行关闭连接四次挥手协议时,最后的ACK是由主动关闭端发出的,如果这个最终的ACK丢失,服务器 ...

随机推荐

  1. Windows系统下在Eclipse中集成Python

    我现在偶尔开发代码,已经不用Eclipse了,主要原因是查看Jar包中的代码反编译十分不便,项目加载的时候卡,偶尔还会崩溃 用Intellij IDEA和PyCharm 原来的笔记如何在Eclipse ...

  2. Linux环境下 RabbitMQ 的下载与安装

    0 环境 CentOS7 RabbitMQ 3.6.5 erlang 18.3 socat rabbitmq是使用erlang语言编写的,所以需要先安装erlang,其次rabbitmq安装依赖于so ...

  3. 理解Fragment的生命周期

    与活动类似,Fragment也有自己的生命周期.理解Fragment的生命周期有助于在Fragment销毁时能恰当地保存其实例,然后在重新创建时能够将其恢复至之前的状态. 下面的“试一试”将研究Fra ...

  4. 算法笔记--java的BigInteger类及BigDecimal类

    引包:import java.math.*; BigInteger类: 可以使用构造方法:public BigInteger(String val),或者valueOf(int)函数,如: BigIn ...

  5. [ORA-28001: the password has expired]的处理

    http://irikintwtr.com/wordpress/?p=420 alter profile default limit password_life_time unlimited; alt ...

  6. Java 历史

    James Gosling 最初开始 Java 语言项目是在 1991 年的 7 月.Java 被用在他的许多 set-top box 工程中.这个语言最开始的时候被称为 Oka,这个是因为 Jame ...

  7. 『cs231n』作业3问题3选讲_通过代码理解图像梯度

    Saliency Maps 这部分想探究一下 CNN 内部的原理,参考论文 Deep Inside Convolutional Networks: Visualising Image Classifi ...

  8. Jenkins安装以及邮件配置

    Jenkins介绍 Jenkins是一个java开发的.开源的.非常好用持续集成的工具,它能帮我们实现自动化部署环境.测试.打包等等的工作,还可以在构建任务成功或者失败之后给我们发邮件通知. 什么叫持 ...

  9. python-day41--数据库---数据类型

    一.存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但宽度是可选的 二.mysql 数据类型 1.数字:(宽度指的是显示宽度,与存储无关)     不用指定宽度, ...

  10. hdu 2266 dfs+1258

    How Many Equations Can You Find Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 ...