Skip to content

tcp ip status

lanzhiwang edited this page Apr 16, 2019 · 7 revisions

tcp connect process

tcp disconnect process

TCP Connection States

Following is a brief explanation of this handshake. In this context the "client" is the peer requesting a connection and the "server" is the peer accepting a connection. 以下是此握手的简要说明。

Note that this notation does not reflect Client/Server relationships as an architectural principal.

Connection Establishment 连接建立

  • The client sends a SYN message which contains the server's port and the client's Initial Sequence Number (ISN) to the server (active open).

  • The server sends back its own SYN and ACK (which consists of the client's ISN + 1).

  • The Client sends an ACK (which consists of the server's ISN + 1).

Connection Tear-down (modified three way handshake). 连接拆除(修改后的三次握手)。

  • The client sends a FIN (active close). This is a now a half-closed connection. The client no longer sends data, but is still able to receive data from the server. Upon receiving this FIN, the server enters a passive close state. 客户端发送FIN(活动关闭)。 这是一个半封闭的连接。 客户端不再发送数据,但仍能够从服务器接收数据。 收到此FIN后,服务器进入被动关闭状态。

  • The server sends an ACK (which is the clients FIN sequence + 1)

  • The server sends its own FIN.

  • The client sends an ACK (which is server's FIN sequence + 1). Upon receiving this ACK, the server closes the connection. 客户端发送ACK(服务器的FIN序列+ 1)。 收到此ACK后,服务器将关闭连接。

A half-closed connection can be used to terminate sending data while sill receiving data. Socket applications can call shutdown with the second argument set to 1 to enter this state.

Here I am assuming webserver1 initiates the close of connection.

Say there is a socket connection established between webserver1 and webserver2. This would be the closing sequence, once the data transfer is done: (From TCP sequence diagram) 假设在webserver1和webserver2之间建立了套接字连接。 完成数据传输后,这将是关闭序列:(来自TCP序列图)

  1. Socket on webserver1 sends a TCP segment with FIN bit (in TCP header) and the socket goes into FIN_WAIT_1 state.

  2. Socket on webserver2 receives the FIN and responds back with ACK to acknowledge the FIN and the socket goes to CLOSE_WAIT state.

Now until the application calls the close() on this socket this is going to be in CLOSE_WAIT state.

  1. Socket on webserver1 receives the ACK and changes to FIN_WAIT_2

  2. Socket on webserver2 closes the connection(once the application calls close()) and sends back FIN to its peer to close the connection and changes its state to Last Ack

  3. Socket on webserver1 receives the FIN and sends back ACK.

At this point the socket implementation on webserver1 would start a timer (TIME_WAIT) to handle the scenario where last ACK has been lost and server resends FIN. 此时,webserver1上的套接字实现将启动一个计时器(TIME_WAIT)来处理上次ACK丢失且服务器重新发送FIN的情况。 Now the socket would wait for 2* MSL (Maximum segment lifetime- default is 4mins for solaris & windows)

  1. Socket on webserver2 receives the ACK and it moves the connection to closed state

  2. After TIME_WAIT is elapsed socket/connection will be closed on webserver1.

These multiple levels of acknowledgments & retransmits are needed since TCP is a reliable protocol unlike basic UDP 由于TCP是与基本UDP不同的可靠协议,因此需要这些多级别的确认和重传

State explanations as shown in Netstat

State Explanation

  • LISTEN Server is ready to accept connection.

  • SYN_SEND Indicates active open.

  • SYN_RECEIVED Server just received SYN from the client.

  • ESTABLISHED Client received server's SYN and session is established.

  • FIN_WAIT_1 Indicates active close.

  • CLOSE_WAIT Indicates passive close. Server just received first FIN from a client.

  • FIN_WAIT_2 Client just received acknowledgment of its first FIN from the server.

  • LAST_ACK Server is in this state when it sends its own FIN.

  • TIMED_WAIT Client enters this state after active close.

  • CLOSED Server received ACK from client and connection is closed.

As an example, consider the following scenario:

A socket application has been terminated, but Netstat reports the socket in a CLOSE_WAIT state. This could indicate that the client properly closed the connection (FIN has been sent), but the server still has its socket open. This could be the result of one instance (among all threads or processes) of the socket not being closed. 套接字应用程序已终止,但Netstat报告该套接字处于CLOSE_WAIT状态。 这可能表明客户端已正确关闭连接(已发送FIN),但服务器仍然打开其套接字。 这可能是套接字未关闭的一个实例(在所有线程或进程中)的结果。

NOTE: It is normal to have a socket in the TIME_WAIT state for a long period of time. The time is specified in RFC793 as twice the Maximum Segment Lifetime (MSL). MSL is specified to be 2 minutes. So, a socket could be in a TIME_WAIT state for as long as 4 minutes. Some systems implement different values (less than 2 minutes) for the MSL.

Difference between close_wait and time_wait

If we take snapshot of netstat (netstat -nP tcp) the common states we see would be ESTABLISHED,TIME_WAIT, CLOSE_WAIT. I will try explaining what they mean.

Before we go into TIME_WAIT and CLOSE_WAIT, lets take close look at sequence of steps for socket closing. Socket connection is essentially between two peers (Browser to webserver, a java client to webserver, webserver to DB server, a webserver to another webserver etc ) 在我们进入TIME_WAIT和CLOSE_WAIT之前,让我们仔细看看套接字关闭的步骤顺序。套接字连接本质上是两个对等体之间(浏览器到网络服务器,java客户端到网络服务器,网络服务器到数据库服务器,网络服务器到另一个网络服务器等)

Here is what the three states mean:

  • ESTABLISHED This is pretty explanatory which basically means the two ends are in a state where data transfer can occur or occurring in both directions. (tcp socket is full duplex, i.e data can be received and responded to on same channel) 这是非常明确的解释,这基本上意味着两端处于可以在两个方向上发生或发生数据传输的状态。 (tcp套接字是全双工的,即可以在同一个通道上接收和响应数据)

  • CLOSE_WAIT This is a state where socket is waiting for the application to execute close(),CLOSE_WAIT is not something that can be configured where as TIME_WAIT can be set through tcp_time_wait_interval (The attribute tcp_close_wait_interval has nothing to do with close_wait state and this was renamed to tcp_time_wait_interval starting from Solaris 7),A socket can be in CLOSE_WAIT state indefinitely until the application closes it. Faulty scenarios would be like filedescriptor leak, server not being execute close() on socket leading to pile up of close_wait sockets. (At java level, this manifests as "Too many open files" error) 这是套接字等待应用程序执行close()的状态,CLOSE_WAIT不能配置,因为可以通过tcp_time_wait_interval设置TIME_WAIT(属性tcp_close_wait_interval与close_wait状态无关,并且从Solaris 7开始重命名为tcp_time_wait_interval) 套接字可以无限期处于CLOSE_WAIT状态,直到应用程序关闭它。错误的场景就像filedescriptor泄漏,服务器没有在socket上执行close()导致堆积close_wait套接字。 (在java级别,这表现为“打开文件太多”错误)

Clone this wiki locally