Skip to content

理解tcp协议连接状态

我们在工作中可能会遇到与连接状态相关的故障,例如半连接队列已满故障。那么什么是半连接队列已满,如何理解TCP协议中的半连接状态呢?

首先我们先来理解TCP协议有哪些连接状态,如何从抓包分析中理解。

TCP connection status

  • LISTEN(监听状态):表示服务器正在监听传入的连接请求。当服务器准备好接受连接请求时,它会处于监听状态。

即当我们启动一个tomcat服务或者netty服务的时候,tomcat服务或netty服务就会监听一个端口,此时服务端处于此状态。

  • SYN_SENT(同步已发送状态):表示客户端已经发送连接请求(SYN)到服务器,等待服务器的确认。

客户端向服务端发起连接,发送第一个握手数据包之后,就会处于此状态。

  • SYN_RCVD(同步已接收状态):表示服务器已经收到客户端的连接请求(SYN),并发送了自己的连接请求(SYN),等待客户端的确认。

服务端接收到客户端的第一次握手数据包并向客户端回复ACK之后,就会处于此状态,此状态也叫半连接状态。

  • ESTABLISHED(已建立连接状态):表示双方已经建立了连接,可以互相发送数据。

当客户端收到服务端的第二次握手数据包并向服务端发送第三次握手数据包后,客户端就处于此状态。 当服务端接收到客户端的第三次握手数据包后,服务端就处于此状态。

  • FIN_WAIT_1(等待对方的连接关闭请求状态):表示连接的一端(通常是客户端)已经发送了关闭请求,等待另一端的确认。

主动断开连接的一方发送FIN数据包之后(第一次挥手),处于此状态。

  • CLOSE_WAIT(等待关闭状态):表示被动关闭的一端(通常是服务端)已经完成数据传输,准备关闭连接。

被动断开连接的一方接收到FIN数据包(第一次挥手)并发送ACK应答(第二次挥手)之后,处于此状态。

  • FIN_WAIT_2(等待对方的连接关闭状态):表示连接的一端(通常是客户端)已经收到关闭请求,并发送了确认,等待另一端关闭连接。

主动断开连接的一方在接收到挥手应答后,处于此状态。

  • LAST_ACK(最后确认状态):表示被动关闭的一端(通常是服务端)已经发送了关闭请求,等待对方的确认。

被动断开连接的一方在发送FIN数据包(第三次挥手)后,处于此状态。

  • TIME_WAIT(等待计时状态):表示连接的一端(通常是客户端)已发送关闭确认,但可能还会接收到延迟的数据包,需要等待2MSL时长。

主动断开连接的一方在收到FIN数据包(第三次挥手的数据包)并发送ACK应答(第四次挥手)之后,处于此状态。

  • CLOSED(关闭状态):表示连接未建立或已经关闭。在关闭状态下,TCP 连接不存在。 对于主动断开连接的一方,处于TIME_WAIT状态并等待2MSL之后,连接变为CLOSED状态。 对于被动关闭连接的一方,在接收到挥手确认(第四次挥手的数据包)后,连接变为CLOSED状态。

半连接队列已满意思就是服务端出现处于SYN_RCVD状态的连接的数量超过了半连接队列的大小。在Linux系统中,默认的半连接队列大小(backlog)通常在128或128-511之间。 如果队列已满,新的连接请求将被拒绝或延迟处理。我们可以通过修改Linux的半连接队列大小来支持更大的并发连接请求。

例如通过sudo sysctl -w net.core.somaxconn=65535命令修改。或者通过echo "65535" > /proc/sys/net/ipv4/tcp_max_syn_backlog命令修改。