TCP状态转换以及TIMEWAIT和FIN_WAIT_2状态

tcp状态转换图

这张图需要分为三个部分去看

第一部分:粗实线部分,表示发起主动连接或主动关闭请求。一般先发起主动连接和断开请求的都为客户端,因此可以认为这部分是客户端的状态变化。

第二部分:虚线部分,表示被动连接和被动关闭请求。一半被动接收连接和关闭请求的都为服务端,因此可以认为这部分是服务端的状态变化。

第三部分:细实线部分,表示两端同时发起连接或关闭请求。

主动连接或主动关闭

        我们先从上到下分析下粗实线部分。客户端初始状态为CLOSED,首先客户端发起主动连接请求,发送一个SYN,然后状态变为SYN_SENT,接下来接收到服务端的回应ACK,表示对连接请求的回应,同时接收到了服务端的一个连接请求SYN,然后客户端对服务端的连接请求作一个回应,回复一个ACK,客户端的状态变为ESTABLISHED。这个过程就是TCP三次握手过程。

        再往下走,客户端发起一个关闭请求FIN,然后状态变为FIN_WAIT_1,然后接收到服务端的回应ACK后,状态变为FIN_WAIT_2,这个时候就处于半关闭状态。继续往下走,客户端接收到服务端发起的关闭请求FIN,客户端对服务端关闭请求做出回应ACK,这个时候状态就变为TIME_WAIT状态。等待2MSL时间后,状态变为CLOSED。这个过程也就是TCP四次挥手过程。

被动连接或被动关闭

        然后我们分析下虚线部分。初始状态为CLOSED,服务端调用accept函数后,进入监听状态LISTEN,然后服务端接收到客户端的连接请求SYN,服务端对连接请求作回应ACK,同时服务端发起连接请求SYN,这个时候服务端状态变为SYN_RCVD,服务端接收到客户端对连接请求回应ACK后,状态变为ESTABLISHED。这个过程为TCP三次握手过程。

        继续沿虚线走,客户端发起一个断开请求FIN,服务端作出回应ACK,然后服务端状态变为CLOSE_WAIT。服务端再发起一个关闭请求FIN,状态变为LAST_ACK,接收到客户端的回应ACK后,状态变为CLOSED。这个过程为四次挥手过程。

两端同时发起请求

        然后分析下细实线部分,两边同时发起连接和关闭请求。接收连接请求SYN的同时发起了连接请求。作出ACK回应后,进入状态ESTABLISHED。 这种情况比较极端。

        继续往下看关闭连接部分,一方发送关闭请求FIN后进入FIN_WAIT_1,同时接收到了对方的关闭请求FIN,回复ACK后状态变为CLOSING。接收到ACK回应后,状态变为TIME_WAIT。如果同时接收到FIN+ACK,并且同时回复了一个ACK,就直接由FIN_WAIT_1进入TIME_WAIT状态。

状态介绍      

CLOSED:表示初始状态。

LISTEN:该状态表示服务器端的某个SOCKET处于监听状态,可以接受连接。

SYN_SENT:这个状态与SYN_RCVD遥相呼应,当客户端SOCKET执行CONNECT连接时,它首先发送SYN报文,随即进入到了SYN_SENT状态,并等待服务端的发送三次握手中的第2个报文。SYN_SENT状态表示客户端已发送SYN报文。

SYN_RCVD: 该状态表示接收到SYN报文,在正常情况下,这个状态是服务器端的SOCKET在建立TCP连接时的三次握手会话过程中的一个中间状态,很短暂。此种状态时,当收到客户端的ACK报文后,会进入到ESTABLISHED状态。

ESTABLISHED:表示连接已经建立。

FIN_WAIT_1:  FIN_WAIT_1和FIN_WAIT_2状态的真正含义都是表示等待对方的FIN报文。区别是:FIN_WAIT_1状态是当socket在ESTABLISHED状态时,想主动关闭连接,向对方发送了FIN报文,此时该socket进入到FIN_WAIT_1状态。FIN_WAIT_2状态是当对方回应ACK后,该socket进入到FIN_WAIT_2状态,正常情况下,对方应马上回应ACK报文,所以FIN_WAIT_1状态一般较难见到,而FIN_WAIT_2状态可用netstat看到。

FIN_WAIT_2:主动关闭链接的一方,发出FIN收到ACK以后进入该状态。称之为半连接或半关闭状态。该状态下的socket只能接收数据,不能发。

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

CLOSING: 这种状态较特殊,属于一种较罕见的状态。正常情况下,当你发送FIN报文后,按理来说是应该先收到(或同时收到)对方的 ACK报文,再收到对方的FIN报文。但是CLOSING状态表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文。什么情况下会出现此种情况呢?如果双方几乎在同时close一个SOCKET的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态,表示双方都正在关闭SOCKET连接。

CLOSE_WAIT : 此种状态表示在等待关闭。当对方关闭一个SOCKET后发送FIN报文给自己,系统会回应一个ACK报文给对方,此时则进入到CLOSE_WAIT状态。接下来呢,察看是否还有数据发送给对方,如果没有可以 close这个SOCKET,发送FIN报文给对方,即关闭连接。所以在CLOSE_WAIT状态下,需要关闭连接。

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

重点知识

TCP这些状态中,我们需要重点掌握三种状态:ESTABLISHED,FIN_WAIT_2,TIME_WAIT

FIN_WAIT_2:进入这个状态后,就处于一个半关闭状态。在面试过程中,很多面试官会问,为什么TCP握手需要三次,而挥手需要四次。就是因为TCP允许半关闭,而半关闭处于的状态就是FIN_WAIT_2

TIME_WAIT:处于这个状态时,需要等待2MSL(这个时间大概为1min)的时间才会进入CLOSED。而为什么要等待这个时间呢,因为TCP是可靠性的传输协议,最后发送一次ACK后,因为不知道对方有没有收到回应,所以要进行一个等待。如果对方没有收到回应,会重新发起断开请求FIN,然后再重新回应ACK。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大草原的小灰灰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值