TCP three-way handshake and four-way waved illustration (finite state machine)

TCP three-way handshake and four-way waved illustration (finite state machine)

Transmission Control Protocol (TCP) is a connection-oriented, reliable, byte stream-based transport layer communication protocol, defined by IETF RFC 793, to provide reliable terminals on unreliable internetwork. A transmission protocol specially designed for end-to-end byte stream. 

An internetwork is very different from a single network, because different parts of the internetwork may have very different topologies, bandwidths, delays, packet sizes, and other parameters. The design goal of TCP is to be able to dynamically adapt to these characteristics of the Internet and have robustness in the face of various failures. 

The application layer sends the data stream represented by 8-bit bytes for inter-network transmission to the TCP layer, and then TCP divides the data stream into segments of appropriate length (usually affected by the data link layer of the network connected by the computer). Maximum transmission unit (MTU) limit). After that, TCP passes the result packet to the IP layer, which then transmits the packet to the TCP layer of the receiving entity through the network. In order to ensure that no packet loss occurs, TCP gives each packet a sequence number, and the sequence number also ensures that the packets sent to the receiving end entity are received in order. Then the receiving entity sends back a corresponding acknowledgment (ACK) to the successfully received packet; if the sending entity does not receive the acknowledgment within a reasonable round-trip delay ( RTT ), then the corresponding data packet is assumed to have been Loss will be retransmitted. TCP uses a checksum function to check the data for errors; checksums are calculated when sending and receiving. 

TCP message header


The meaning of each field is explained below

  • Source and destination port number field : occupies 16 bits (2 bytes). The TCP protocol uses "ports" to identify the source and target application processes. The port number can use any number between 0 and 65535. When receiving a service request, the operating system dynamically assigns a port number to the client's application. On the server side, each service provides services to users on the "well-known port".
  • Sequence number field : occupies 32 bits. It is used to identify the data byte stream sent from the TCP source to the TCP target. It represents the first data byte in this segment. In the stream transmitted by TCP, each byte has a sequence number. For example, if the sequence number of a TCP segment is 301 and it carries 100 bytes of data, it means that the byte sequence number range of the 100 bytes of data is [301, 400], and the first segment carried by the segment is [301, 400]. The first byte sequence number is 301, and the last byte sequence number is 400. Therefore, the sequence number ensures the orderliness of TCP transmission.
  • Confirmation number field : occupies 32 bits. Only when the ACK flag is 1, the acknowledgment number field is valid. It contains the next data byte that the target expects to receive from the source. For example, when a connection is established, the ACK flag bit of the SYN packet is 0.
  • Header length field : occupies 4 bits. Give the number of 32 bits in the header. The length of the TCP header without any option field is 20 bytes; there can be a TCP header of up to 60 bytes. The maximum value that the 4-bit header length field can represent is 1111, which is converted to 15 in decimal, 15*32/8 = 60, so the maximum length of the header is 60 bytes
  • Flag field (U, A, P, R, S, F) : occupies 6 bits. The meaning of each bit is as follows: Window size field: occupies 16 bits. This field is used for flow control. The unit is the number of bytes. This value is the number of bytes that the machine expects to receive at one time.
    • URG : Urgent pointer sign. When it is 1, it means the urgent pointer is valid, and when it is 0, the urgent pointer is ignored.
    • ACK : Acknowledgment sequence number flag. When it is 1, it means that the confirmation number is valid. When it is 0, it means that the message does not contain confirmation information, and the confirmation number field is ignored.
    • PSH : push flag, 1 means it is data with push flag, and instructs the receiver to deliver the message segment to the application as soon as possible after receiving the message segment, instead of queuing it in the buffer.
    • RST : Reset connection flag, used to reset the connection that has been wrong due to host crash or other reasons. Or it can be used to reject illegal segments and connection requests.
    • SYN : Synchronization sequence number, used to establish the connection process. In the connection request, SYN = 1 and ACK = 0 indicate that the data segment does not use the piggybacked confirmation field, and the connection response piggybacks an acknowledgment, that is, SYN = 1 and ACK = 1.
    • FIN : Finish mark, used to release the connection. When it is 1, it means that the sender has no data to send, that is, close the data stream of the local party.
  • TCP checksum field : occupies 16 bits. The checksum calculation is performed on the entire TCP message segment, that is, the TCP header and TCP data, and is verified by the target end.
  • Urgent pointer field : occupies 16 bits. It is an offset, which is added to the value in the sequence number field to indicate the sequence number of the last byte of emergency data.
  • Options and padding : The most common optional field is the maximum message size, also known as MSS (Maximum Segment Size). Each connecting party is usually in the first message segment of the communication (the SYN flag is set to establish a connection This option is specified in the segment of 1), which indicates the length of the maximum segment that can be accepted by the local end. The option length is not necessarily an integer multiple of 32 bits, so add padding bits, that is, add extra zeros in this field to ensure that the TCP header is an integer multiple of 32.
  • Data part : The data part in the TCP segment is optional. When a connection is established and a connection is terminated, the message segment exchanged by both parties has only the TCP header. If one party has no data to send, the header without any data is also used to confirm the received data. In many cases when processing timeouts, segments without any data are also sent.

TCP three-way handshake

TCP is a connection-oriented protocol. Before either party sends data to the other party, a connection must be established between the two parties. The following process is involved in establishing a connection.

  • The first handshake: When establishing a connection, the client sends a syn packet (syn=x) to the server, and enters the SYN_SENT state, waiting for the server to confirm; SYN: Synchronize Sequence Numbers.
  • The second handshake: the server receives the syn packet, it must confirm the client's SYN (ack=x+1), and at the same time it sends a SYN packet (syn=y), that is, the SYN+ACK packet, and the server enters the SYN_RECV state;
  • The third handshake: the client receives the SYN + ACK packet from the server and sends an acknowledgment packet ACK (ack=y+1) to the server. After this packet is sent, the client and server enter the ESTABLISHED (TCP connection successful) state, which is completed three times shake hands.

These three segments complete the connection establishment, and this process becomes a three-way handshake.

SYN attack

In the three-way handshake process, after the Server sends the SYN-ACK, the TCP connection before receiving the Client's ACK is called half-open connect. At this time, the Server is in the SYN_RCVD state. When the ACK is received, the Server transfers to ESTABLISHED status.

The SYN attack is that the client forges a large number of non-existent IP addresses in a short period of time, and continuously sends SYN packets to the server, the server replies to the confirmation packet, and waits for the client to confirm. Until the timeout expires, these forged SYN packets will occupy the unconnected queue for a long time, causing normal SYN requests to be discarded because the queue is full, causing network congestion and even system paralysis.

SYN attack is a typical DDOS attack. The way to detect SYN attack is very simple, that is, when there are a large number of semi-connected states on the Server and the source IP address is random, it can be concluded that the SYN attack has occurred.  


  • 1. Invalid connection monitoring release
  • 2. Delay the TCB allocation method

When a TCP port is opened, the port is in the Listening state, and the Syn packets sent to the port are constantly monitored.

Once the Syn message sent by the Client is received, a TCB (Transmission Control Block) needs to be allocated for the request, and a SYN ACK command is returned, which immediately switches to the SYN-RECEIVED state, which is half-open connection.

Usually a TCB needs at least 280 bytes, in some operating systems TCB even needs 1300 bytes, and some operating systems can open up to 512 half-open connections in the implementation of SOCK.

The main reason for consuming server resources is that when the SYN data message arrives, the system immediately allocates TCB, thus occupying resources.


When receiving a SYN data message, do not rush to allocate TCB, but first respond to a SYN ACK message, and save this half-open connection information in a dedicated HASH table (Cache) until the correct response ACK message is received Redistribute TCB.

TCP terminates the connection process (waves four times)

  1. The client process sends a connection release message and stops sending data. Release the header of the data message, FIN=1, and its sequence number is seq=u (equal to the sequence number of the last byte of the previously transmitted data plus 1), at this time, the client enters FIN-WAIT-1 (terminate waiting 1) Status. TCP stipulates that even if the FIN segment does not carry data, it will consume a sequence number.
  2. The server receives the connection release message and sends an acknowledgment message, ACK=1, ack=u+1, and brings its own serial number seq=v. At this time, the server enters the CLOSE-WAIT state. . The TCP server informs the high-level application process that the client is released in the direction of the server. At this time, it is in a half-closed state, that is, the client has no data to send, but if the server sends data, the client still has to accept it. This state will continue for a while, that is, the duration of the entire CLOSE-WAIT state.
  3. After the client receives the server's confirmation request, at this time, the client enters the FIN-WAIT-2 (termination waiting 2) state, waiting for the server to send a connection release message (before that, it needs to accept the last data sent by the server) .
  4. After the server has sent the final data, it sends a connection release message to the client, FIN=1, ack=u+1. Because it is in the semi-closed state, the server is likely to send some more data, assuming the serial number at this time Seq=w, at this time, the server enters the LAST-ACK (last confirmation) state, waiting for the client's confirmation.
  5. After the client receives the server's connection release message, it must send an acknowledgment, ACK=1, ack=w+1, and its own serial number is seq=u+1, at this time, the client enters TIME-WAIT ( Time waiting) status. Note that the TCP connection has not been released at this time, and the time of 2 MSL (the longest message segment life) must pass, and the client can enter the CLOSED state after canceling the corresponding TCB.
  6. As long as the server receives the confirmation from the client, it immediately enters the CLOSED state. Similarly, after canceling the TCB, this TCP connection is ended. It can be seen that the server ends the TCP connection earlier than the client.

TCP state machine


The figure above is the state machine of TCP.

  1. CLOSED: The initial state is the state.

  2. LISTEN: Passively open, the status of the server changes to LISTEN (listening). The concept of passive opening: the application at one end of the connection informs the operating system that it wants to establish an incoming connection. At this time, the operating system establishes a connection for this end of the connection. Corresponding to it is active connection: the application tells the operating system to establish a connection by actively opening a request.

  3. SYNRECVD: After the server receives SYN, the status is SYN; send SYN ACK;

  4. SYN_SENTY: After the application sends SYN, the status is SYN_SENT;

  5. ESTABLISHED: After SYNRECVD receives ACK, the status is ESTABLISHED; SYN_SENT receives SYN ACK and sends ACK, and the status is ESTABLISHED;

  6. CLOSE_WAIT: After receiving the FIN, the server sends an ACK, and the status is CLOSE_WAIT; if the server still has data to send at this time, then send it until the data is sent; at this time, the server sends FIN, and the status becomes LAST_ACK;

  7. FIN_WAIT_1: The application program sends FIN, ready to disconnect the TCP connection; the status is from ESTABLISHED -> FIN_WAIT_1;

  8. FIN_WAIT_2: The application side only received the ACK signal from the server side, but did not receive the FIN signal; indicating that there is still data transmission on the server side, then it is a semi-connection at this time;

  9. TIME_WAIT: There are two ways to enter this state:

    • FIN_WAIT_1 entry: At this time, the application port receives FIN+ACK (instead of only receiving ACK like FIN_WAIT_2, indicating that the data has been sent) and sends an ACK to the server port;
    • FIN_WAIT_2 entry: At this time, the application port receives the FIN, and then sends an ACK to the server; TIME_WAIT is to achieve the reliability of the TCP full-duplex connection, and is used to retransmit the ACK message that may be lost; it needs to last 2 MSL ( Maximum message survival time): Assuming that the application port does not receive FIN within 2 MSLs after entering TIME_WAIT, it means that the last ACK sent by the application has been received; otherwise, ACK will be received here within 2 MSLs Message

State transition diagram of the client application

The state of the client can be represented by the following process:


The above process is the process that should exist when the program is normal. From the figure in the book, you can see that when the connection is established, when the client receives the ACK of the SYN message, the client opens the data interactive connection . The end of the connection is usually the client actively ends. After the client ends the application, it needs to go through the FIN_WAIT_1, FIN_WAIT_2 and other states. The transition of these states is the four-way handshake for ending the connection mentioned earlier.

State transition diagram of the server

The status of the server can be represented by the following process:

CLOSED -> LISTEN -> SYN received -> ESTABLISHED -> CLOSE_WAIT -> LAST_ACK -> CLOSED copy the code

When establishing a connection, the server enters the data interaction state after the third handshake, and the connection is closed after the second handshake (note that it is not the fourth time). After closing, you have to wait for the client to give the final ACK packet before entering the initial state.

Other state transitions

The pictures in the book also have some other state transitions. These state transitions are summarized as follows for both the server and the client.

  • LISTEN -> SYN_SENT , the explanation for this is very simple, sometimes the server has to open the connection.
  • SYN_SENT -> SYN received , if the server and client receive a SYN datagram in the SYN_SENT state, they both need to send the SYN ACK datagram and adjust their state to the SYN received state, ready to enter ESTABLISHED
  • SYN_SENT -> CLOSED , in the case of sending timeout, it will return to the CLOSED state.
  • SYN_ received -> LISTEN , if it receives RST packet, it will return to LISTEN state.
  • SYN_receive -> FIN_WAIT_1 , this migration means that instead of going to the ESTABLISHED state, you can jump directly to the FIN_WAIT_1 state and wait for it to be closed.

2 MSL waiting state

In the picture given in the book, there is a TIME_WAIT waiting state, which is also called the 2 MSL state. It means that after TIME_WAIT2 sends the last ACK datagram, it must enter the TIME_WAIT state. This state is to prevent the datagram from the last handshake. It was prepared without being sent to the other party (note that this is not a four-way handshake, this is the insurance status of the fourth handshake). This state to a large extent guarantees that both parties can end normally, but the problem has also come.

Due to the 2MSL status of the socket (socket is the meaning of IP and port pair, socket), the application cannot use the same socket again within 2 MSL, which is better for client programs, but for service programs, such as httpd, It always uses the same port for service, and within 2 MSL, an error occurs when httpd is started (the socket is used). In order to avoid this error, the server gives a notion of quiet time, which means that although the server can be restarted within 2 MSL time, the server still has to wait for the 2 MSL time to pass before making the next connection.

FIN_WAIT_2 status

This is the well-known half-closed state, which is the state after the client and server handshake twice when the connection is closed. In this state, the application still has the ability to receive data, but it has been unable to send data, but there is also a possibility that the client has been in the FIN_WAIT_2 state, and the server has been in the WAIT_CLOSE state until the application layer decides to close this status.

RST, both open and close at the same time

RST is another way to close the connection. The application should be able to determine the authenticity of the RST packet, that is, whether it is aborted. At the same time, opening and closing at the same time are two special TCP states, and the probability of occurrence is very small.

Common interview questions

[Question 1] Why is there a three-way handshake when connecting, but a four-way handshake when closing?

Answer: Because when the server receives the SYN connection request message from the client, it can send a SYN+ACK message directly. The ACK packet is used for reply, and the SYN packet is used for synchronization. But when the connection is closed, when the server receives a FIN message, it may not immediately close the SOCKET, so it can only reply an ACK message first to tell the client, "I received the FIN message you sent." Only after all the messages on my Server side have been sent, I can send FIN messages, so I cannot send them together. Therefore, a four-step handshake is required.

[Question 2] Why does the TIME_WAIT state need to pass 2MSL (maximum segment survival time) before returning to the CLOSE state?

Although it is reasonable to say that the four messages have been sent, we can directly enter the CLOSE state, but we must assume that the network is unreliable, and the last ACK may be lost. So the TIME_WAIT state is used to retransmit ACK messages that may be lost. The client sends the final ACK reply, but the ACK may be lost. If the server does not receive an ACK, it will repeatedly send FIN fragments. Therefore, the Client cannot be closed immediately, it must confirm that the Server has received the ACK. The Client will enter the TIME_WAIT state after sending the ACK. Client will set a timer to wait for 2MSL time. If the FIN is received again within this time, the Client will resend the ACK and wait for 2 MSL again. The so-called 2 MSL is twice the MSL (Maximum Segment Lifetime). MSL refers to the maximum survival time of a segment in the network, and 2MSL is the maximum time required for a transmission and a reply. If the Client does not receive the FIN again until 2 MSL, the Client concludes that the ACK has been successfully received, and ends the TCP connection.

[Question 3] Why can't I connect with two handshake?

The three-way handshake completes two important functions. Both parties need to prepare to send data (both parties know that each other is ready), but also allow both parties to negotiate the initial sequence number, which is sent during the handshake. And confirm.

Now change the three-way handshake to only need two handshake, deadlock is possible. As an example, consider the communication between computers S and C. Suppose that C sends a connection request packet to S, and S receives this packet and sends an acknowledgement response packet. According to the two handshake agreement, S thinks that the connection has been successfully established and can start sending data packets. However, when the response packet of S is lost during transmission, C will not know whether S is ready or what sequence number S has established. C even suspects whether S has received its own connection request packet. In this case, C thinks that the connection has not been successfully established, and will ignore any data packets sent by S, and only wait for the connection confirmation response packet. And S sends the same packet repeatedly after the outgoing packet times out. This creates a deadlock.

[Question 4] What should I do if the connection has been established, but the client suddenly fails?

TCP also has a keep-alive timer. Obviously, if the client fails, the server cannot wait forever, and resources are wasted. The server resets this timer every time it receives a request from the client. The time is usually set to 2 hours. If it has not received any data from the client for two hours, the server will send a probe segment, and then every 75 Sent once every second. If there is no response after sending 10 probe packets, the server thinks that the client is faulty, and then closes the connection

Other articles


Reference article