我们先来看四种比较特殊的TCP状态
TIME_WAIT状态
FIN_WAIT_2状态
同时打开状态
同时关闭状态
其中前两种状态较为常见而后两种状态出现频率较低。
TIME_WAIT状态
TIME_WAIT状态也被称为2MSL等待状态。MSL的全称是Maximum Segment Lifetime即报文的最大生存时间。它是所有报文在被遗弃前在网络内的最长有限时间。由于TCP的报文段依靠IP数据包在网络内传输而IP数据包有TT2字段限制其生存时间。RFC793曾指出MSL为2分钟然而其实际时间可以是30秒、1分钟或者2分钟。
(TIME_WAIT状态)
针对一个具体时限所给定的MSL值的处理方法如下
当TCP执行一个主动关闭并发回最后一个确认ACK该连接必须在TIME_WAIT状态停留2倍的MSL时长这样做可以让TCP再次发送最后的ACK以防其丢失。该TCP连接在2MSL等待期间定义该连接的Socket将无法再次使用只能在2MSL结束后才能再次使用。
FIN_WAIT_2状态
当发起端主动关闭FIN并且收到对端的确认信息此时发起端的TCP进入FIN_WAIT_2状态。在未收到对端的FIN时TCP连接处于半关闭状态而对端处于CLOSE_WAIT状态且在等待应用层的结束通知。除非我们可以维持半关闭状态否则只有在对端应用层发出文件结束符说明TCP才会发出FIN关闭另一个方向的连接。只有另一端的进程完成这个关闭才会从FIN_WAIT_2的状态进入TIME_WAIT状态并发出最后的ACK对端的TCP正式关闭连接发送端在经过2MSL等待以后也将关闭TCP连接。同时这也意味着如果应用层发生了故障没有通知TCP结束发送端会永远保持在FIN_WAIT_2状态而对端也将持续处于CLOSE_WAIT状态直至应用层恢复正常发出关闭的通知。开发者往往会通过设置TCP定时器规避此类问题。如果连接一段空闲时间比如10分57秒TCP将自动进入CLOSE状态。
(FINE_WAIT_2状态)
同时打开状态
两个应用程序同时主动打开的情况比较少不经常出现。这种状态往往要求双方各自发送一个SYN且必须保证这些SYN传递给对方需要双方使用对方数值的端口为本地端口。当出现同时打开状态时连接状态与标准的连接状态不同。两端几乎同时发送SYN并进入SYN_SENT状态。当一端收到SYN时状态变为SYN_RCVD同时它们将再次发送SYN并对收到对方的SYN进行确认。当双方都接收到SYN以及相应的ACK后状态就都变成了ESTABLISHED。一个同时打开的连接需要交互4个报文段比正常的三次握手多一个。该状态下没有任何一端可以作为客户端或者服务器端因为他们既充当客户又充当服务器。
(图片源于网络)
同时关闭状态
正常情况下连接是通过一方发送FIN来关闭的但是双方同时执行主动关闭也有可能发生。当应用层发出关闭命令时双方的连接均从ESTABISHED变为FIN_WAIT_1这将导致双方各发送一个FIN两个FIN经过网络传输后分别到达对端收到FIN后状态由FIN_WAIT_1变为CLOSED并将发送最后的ACK双方收到最后的ACK后状态均变为TIME_WAIT。
(图片源于网络)
TCP各种状态的变迁
了解完这四种特殊的TCP状态我们一起再来看这些状态是如何变化的。
(TCP应用状态变迁)
首先请求端的初始状态是CLOSED接收端的初始状态是LISTEN请求端应用主动通知TCP打开连接TCP的状态由CLOSED变为SYN_SENT并发出SYN同时启动三次连接接收端收到SYN以后TCP的状态由LISTEN变为SYN_RCVD并通知应用层接收数据应用层被动打开TCP同时回复SYN_ACK给请求端请求端收到SYN_ACK医护TCP的状态变为ESTABLISHED这就标明请求端的连接已经建立完成并且同时回复ACK当接收端收到ACK后TCP的状态改为ESTABLISHED表明请求端的连接已经建立完成并同时回复ACK当接收方收到ACK后TCP的状态变为ESTABLISHED表明请求端的连接已建立完成并同时回复ACK当接收端收到ACK后TCP的状态改为ESTABISHED接收端的连接也建立完成同时意味着TCP的三次握手正式完成。
之后应用层进入数据处理状态TCP进入数据传输状态。当数据传输结束以后应用程序首先进入主动关闭状态并通知TCP可以断连此时请求端的应用程序正式关闭而TCP进入FIN_WAIT_1状态并发出FIN报文。接收端收到FIN报文后将状态改为CLOSE_WAIT并通知应用层对端的连接已经关闭返回ACK确认信息应用程序被动关闭当请求端收到接收端的ACK回复后把TCP的状态改为FIN_WAIT_2并开始等待对端的FIN报文此时的TCP连接就此处于半关闭状态。
当接收端的应用程序确定关闭之后应用层通知TCP断连TCP把状态置为LAST_ACK并发出最后的FIN报文请求端收到FIN报文后把状态置为TIME_WAIT并发出最后的ACK。经过2MSL等待后TCP连接正式关闭同时释放TCP的连接资源接收方收到最后的ACK后释放TCP连接端口回到初始的LISTEN状态并等待新的连接。
8分钟看懂TCP状态变迁点击扫码☝观看视频吧
点击扫码☝观看视频吧