在平常运维服务器的时候,需要查看各种连接状态,所以必须要对TCP连接状态非常熟悉才知道每个状态的意义;只有知道了这些参数的意义才可以相对应的优化。

查看状态命令:

[root@tomcat10 logs]# netstat -na | awk '/^tcp/{s[$6]++}END{for(key in s) print key,s[key]}'
TIME_WAIT 1443
CLOSE_WAIT 1122
SYN_SENT 3
FIN_WAIT1 2074
FIN_WAIT2 195
ESTABLISHED 89782
SYN_RECV 7314
LISTEN 9
CLOSING 9
LAST_ACK 2372

各个状态的意义如下 :

  • LISTEN:表示监听的TCP端口已经打开; 

  • SYN_SENT:客户端在发送建立连接(SYN)请求后的状态; 

  • SYN_RECV:服务端在收到SYN请求建立连接后,发送SYN+ACK后的状态; 

  • ESTABLISHED:客户端在发送完ACK后的状态、服务端在收到ACK后的状态,此时连接正式建立; 

  • FIN_WAIT1:客户端发送完FIN后的状态;

  • CLOSE_WAIT:服务端收到客户端的FIN请求后,发送对FIN的ACK后的状态; 

  • FIN_WAIT2:收到服务端发送的对之前FIN的ACK后的状态; 

  • LAST_ACK:服务端处理完最后的数据,发送FIN后的状态;

  • TIME_WAIT:收到服务端发送的FIN后的状态,表示处于空闲等待阶段; 

  • CLOSED:TIME_WAIT时间到达后,发送对FIN的确认ACK后的状态,发送完ACK表示连接已关闭 ;

  • CLOSING:连接双方同时发送关闭请求和确认时的状态; 

三次握手四次断开流程示意:

    TCP建立连接和关闭连接的流程及状态变化_tcp

关于四次断开:

   a.先由客户端向服务器端发送一个FIN,请求关闭数据传输。

   b.当服务器接收到客户端的FIN时,向客户端发送一个ACK,其中ack的值等于FIN+SEQ

   c.然后服务器向客户端发送一个FIN,告诉客户端应用程序关闭。

   d.当客户端收到服务器端的FIN是,回复一个ACK给服务器端。其中ack的值等于FIN+SEQ

为什么要4次才能断开?
   a.确保数据能够完成传输。

   b.但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;

   c.但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后

   d.再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。