TCP端口的连接状态

今天做卷子遇到了一个关于TCP的基础问题,是TCP的端口状态,这个问题还是有点棘手的,特别写一篇笔记记一下TCP端口状态。

LISTEN

侦听状态,等待来自网络上其他设备发出的TCP连接请求到达端口。只有在该端口上开启了某个服务之后,端口才会进入LISTEN状态。

只要服务没有被连接且端口是开放的,那么端口就会一直处于LISTEN状态侦听连接请求。该状态只属于服务端,不属于客户端。

SYN_SENT

只属于客户端的状态,涉及到TCP的三次握手。

TCP的三次握手是客户端先发送SYN报文,置发送序号为X,服务端收到该报文后返回SYN+ACK报文(ACK报文是确认客户端发来的SYN,再发SYN是给客户端确认),设置发送序号为Y,并且设置ACK的序号为X+1。

客户端收到了服务器的SYN+ACK报文,再次向服务器发送一个ACK,序号为Y+1。

在三次握手中,客户端发出了SYN报文后端口就进入了SYN_SENT状态。

SYN_RECV

只属于服务端的状态,服务端在收到了客户端的SYN之后,向客户端发送SYN+ACK,发送之后服务端进入SYN_RECV状态。

ESTABLISHED

连接已经建立,双方开始通过连接传输数据。该状态在三次握手完成后,客户端和服务端双方一起进入。

FIN-WAIT-1

这个状态是在连接要关闭的时候端口进入的状态,涉及到TCP关闭连接的四次挥手。

TCP连接是全双工的,双方可以同时向对方发送或接收数据。在连接要关闭的时候,每个方向需要单独关闭。

如果有一方要关闭连接,那么它会发送FIN告诉对方连接要关闭了,等待对方回复ACK,此时关闭一个方向的连接。这个关闭连接只关闭了单向的,另一方仍然还可以发送数据,当数据传输完成后,发送方发送FIN,接收方收到后回复ACK,连接真正关闭。

对于FIN_WAIT_1这个状态,它是某一方要主动关闭连接时(此时双方端口状态都是ESTABLISHED),先向对方发送了FIN报文,然后进入FIN_WAIT_1等待对方回复ACK。

一旦收到ACK报文,那么端口立即进入FIN_WAIT_2状态。

FIN_WAIT_2

FIN_WAIT_2是收到被动关闭连接的一方发送关闭连接的ACK后进入的等待状态,端口等待被动关闭连接的一方关闭另一条连接。

CLOSE_WAIT

这个状态出现去四次挥手中被动关闭连接的一方,它在收到了对方的FIN报文之后,回复对方的ACK,此时自己进入CLOSE_WAIT状态。

在这个状态下作为被动关闭连接的一方,它还保持向另一方的连接。比如A先向B主动关闭连接,关闭的是A到B的连接,但是B到A的连接还是保持的,可以继续传输数据。

这个时候在CLOSE_WAIT状态下,B可以考虑向A继续传输数据,数据传输完成之后向A发送FIN,结束B到A方向的连接。

LAST_ACK

在传输数据完成,关闭最后一个方向连接的时候,只要FIN发送了,那么端口机会进入LAST_ACK状态,等待对方发送最后的ACK。

TIME_WAIT

在主动关闭连接的一方,当收到对方关闭另一方向连接的FIN时,它会向对方发送ACK,然后进入TIME_WAIT状态。这个状态下端口会等待2MSL后关闭,回到CLOSED状态。

MSL指最大报文段生存时间,通常是两分钟,超时意味着这个报文段在网络中已经被废弃了。

之所以等待2MSL而不是立刻关闭,主要原因是自己发送的ACK可能没有被对方接到,对方可能会在等待超时之后重发一个FIN包,此时主动断开连接的一方要是接收到了这个重发的FIN还可以回复。

严格意义上只需要等待服务器的超时等待时间 + FIN的传输时间即可,但为了保证连接的关闭更加可靠,取等待时间为2MSL

除此之外等待2MSL也可以保证已经关闭的连接其数据在网络中已经全部彻底失效,不会有一些在网络中滞留的、迟到的数据到达新的、使用同一端口的连接中干扰通信。

CLOSING

这个双状态是通信的双方中,主动关闭连接的A发送了FIN,但是在发送之后没有收到被动关闭连接的一方发送的ACK,而是直接收到了FIN,两个端口都进入了CLOSING状态,两边都在尝试关闭连接。

在这个状态下,端口会继续等待ACK,接收到ACK后进入TIME_WAIT状态。

CLOSED

指端口没有开启服务,没有被用于通信,处于关闭状态。