How to answer TCP three-way handshake and four-time wave with lots of interview questions

Less code, more hair

Three handshake to establish a link, four waves to break the link. This question is a very classic question and one the interviewer likes to ask.

It is no exaggeration to say that when Uncle Long recruited interviews at the school, every company had asked questions about three handshakes and four wavers.

The importance of this issue has been realized. Don't talk nonsense, the next step is to listen to the clear arrangements made by Uncle Long for you.

First draw a picture to see the overall process of establishing and disconnecting TCP.

TCP handshake three times and waves four times
TCP handshake three times and waves four times

After reading this picture, I believe that you are smart and have some basic control over three handshakes and four wavers. However, the details inside will definitely be a little rusty or vague, and then the essence of the problem will be revealed one by one.

Before explaining, first look at the basics to make a foreshadowing.

TCP state transfer explained

status description
CLOSED Blocked or closed state, indicating that the host is not currently transmitting or establishing a link
LISTEN Monitoring status, indicating that the server is ready to wait for the establishment of a transmission link
SYN RECV Received the first transmission request without confirmation
SYN SENT After sending the first SYN message, waiting for confirmation
ESTABLISHED Enter the data transmission stage after the link is established normally
FIN WAIT1 Enter this state after actively sending the first FIN message
FIN WAIT2 Has received the confirmation signal of the first FIN, waiting for the other party to send a close request
TIMED WAIT Complete the two-way link close and wait for the packet to disappear
CLOSING When both parties close the request at the same time, waiting for the other party to confirm
CLOSE WAIT Receive the other party's shutdown request and confirm to enter this state
LAST ACK Wait for the last message to confirm the shutdown

Look at the TCP message format again

TCP message format
TCP message format

The header has a fixed length of 20 bytes, the meaning is as follows:

  1. Source port and destination port

2 bytes each, which stores the source port number and destination port

  1. Seq

It takes 4 bytes, and the range indicated is the range of shaping [0 ~ 2 ^ 32]. The serial number is used to number each byte of the data part, and the numbering method is mod 2 ^ 32.

  1. Confirmation number ack

It takes 4 bytes and the range is also the range of unsigned integers. Use the last byte sequence number of the data transmitted to me at the opposite end, for example, A is transmitted to B 101-500. At this time, the confirmation number returned by B must be less than or equal to 501. The confirmation number will only be returned after the B segment receives the data correctly. In other words, all the data before the confirmation number has been received.

  1. Data offset

It takes 4 bits, and the data is off. Many people can easily think whether it means the length of the data, which is wrong. The offset refers to the offset from the start position of the TCP to the start position of the data part, that is, the length of the TCP header.

  1. Keep

It occupies 6 bits. The reserved field, as the name implies, is for future use, and is set to 0 by default.

  1. Emergency URG control bit

Occupy 1bit, URG = 1, indicating that the emergency pointer is valid, at this time tcp data is preferentially transmitted. It is equivalent to an emergency passage in life, and is used in special situations.

There will also be special situations in the network, for example, sending a long program to run on a remote server, at this time it is found that the program has a bug and needs to be interrupted, so we enter Ctrl c from the keyboard. If you do not use emergency data, you need to Queued in the buffer zone, we all know that it is a bug, and we still have to queue up, I am afraid it will be out of the pan.

At this time, emergency data transmission is used, and there is no need to queue. Is it more in line with our expectations to directly interrupt the program?

It should be noted that even when the window is 0, emergency data can be sent.

How to use the emergency URG control bit, the flag parameter of the send function in socket programming

send(int socket, const void *buffer, size_t length, int flags);

When the flags parameter passes the MSG_OOB macro, it indicates that there is urgent data at this time. MSG_OOB is a macro,

  1. Confirm ACK

It takes 1 bit, and takes effect when ACK = 1. TCP has a hard and fast rule that all data packets transmitted must set ACK to 1 when the connection is established successfully.

  1. Push PSH

It takes 1 bit. When the sender sets PSH to 1, the data packet will be sent immediately, and the receiver will immediately process the packet with PSH = 1 and deliver it to the application layer for processing. Does it feel very similar to URG, but there are still some differences.

  • The two are similar:

Both URG and PSH are used in emergency handling situations to quickly transmit emergency data.

  • The difference between the two

When URG is set to 1, for sending, "out-of-band data" is encapsulated into datagrams to be sent together with the message data that should be sent under normal circumstances, eliminating the waiting time in the queue. On the receiving side, after parsing the message, it still needs to be placed in the cache area after the data is obtained, and after being full, it is delivered upward to the application layer.

When PSH is set to 1, for the sender, it means that the data does not need to wait for the buffer area to be sent down to be full, immediately encapsulated into a message, and sent, eliminating the time to wait for the buffer to reach the full state. On the receiving side, there is no need to wait for the receiving buffer to be full and deliver it directly to the application layer.

  1. Reset RST

Occupy 1bit, when RST = 1, TCP will actively release the link, two cases will be used.

When a serious error occurs in TCP, it will actively release the connection, reestablish the connection, and transmit the data.

When it encounters illegal packets or refuses to connect, it will set RST to 1.

  1. Synchronous SYN

Occupy 1bit, synchronous control bit, used to synchronize the transmission serial number when the transmission connection is established.

When SYN = 1, it means that this is a connection request or connection confirmation message.

SYN = 1, ACK = 0, indicating that this is a connection request data segment, if the other party agrees to establish a connection, the other party will return a confirmation of SYN = 1, ACK = 1.

  1. FIN control bit

It occupies 1 bit and is used to release a transmission connection.

When FIN = 1, it means that the data has been completely transmitted, and the sender has no data to transmit, requesting to release the current connection, but the receiver can still continue to receive the data that has not been received.

FIN = 0, normal data transmission.

  1. Window size

It occupies 16bit, 2byte and is used to indicate the maximum data size that the sender can accept.

This window changes dynamically and is used for flow control.

  1. Checksum

16bit, 2byte, used to check the TCP header, pseudo header, and data.

  1. Emergency pointer

It occupies 16bit, 2byte and is used to record the position of the end of emergency data in the data segment .

When URG = 1, the pointer takes effect.

  1. Optional

The options can be up to 40 bytes long, which is optional and can be omitted. When the optional item does not exist, the TCP header length is 20 bytes.

Options can include Window Scale Options (WSopt), MSS (Maximum Data Segment Size) options, SACK (Selective Acknowledgement) options, Timestamp (Timestamp) options, etc.

  1. data

The TCP data part is the data submitted by the application program at the application layer.

The TCP header is the basic knowledge. You must understand it to better understand how TCP data is encapsulated and transmitted, and to operate those places when establishing and disconnecting links.

Three-way handshake to establish a connection

How does a three-way handshake establish a connection?

Three-way handshake to establish a link
Three-way handshake to establish a link

It can be clearly seen from the figure that during the three-way handshake, I am explaining the process clearly, and by the way, the knowledge points that are easily asked in each process.

Adopt C / S mode to explain, suppose C end initiates the transmission request.

Before sending a link establishment request, the C terminal maintains the CLOSED state, and the S terminal is initially in the CLOSED state. When the listen function is executed, the socket enters the passive listening state .

The so-called passive monitoring means that when there is no client request, the socket is in the "sleep" state. Only when the client request is received, the socket will be "awakened" to respond to the request.

The first time: the C terminal sends a request message with SYN = 1, at this time the C terminal enters the SYN SENT state, waiting for the server to confirm.

What happens if the packet is lost and cannot be sent to the peer at this time?

After sending a message, the C terminal will start a timer. After the timeout, if no confirmation is received from the S terminal, a SYN request will be sent again. The time of each attempt will be twice that of the first time. Seconds, the link establishment failed this time.

The second time: After the S end receives the SYN message (link establishment request) sent by the C end, the S end must return the confirmation number and send a SYN message at the same time, then enter the SYN RCVD state.

Why send SYN messages together?

TCP is full-duplex communication. The protocol stipulates that when receiving a link establishment request, it must return the serial number and establish a local-to-peer communication link. This is also called a piggyback response mechanism.

What if the second message is lost?

After sending the ACK + SYN message, a timer will be started. If the ACK is not received after timeout, it will be sent again, and multiple retries will be made. The timeout period is still doubled each time, and the number of retries can be set.

Modify /proc/sys/net/ipv4/tcp_synack_retriesthe value

image-20200412205846062

The third time: The C terminal receives the ACK + SYN message sent by the S terminal and needs to return an ACK response message. At this time, the connection will enter the semi-connected queue. When the S terminal receives the ACK, a complete The full-duplex TCP link is established, and both parties enter the ESTABLISHED state.

There is a common attack method here. The attacker forges a SYN request and sends it to the server. After the server responds, it will not receive the ACK confirmation from the C side. The server will retry continuously. By default, it will retry five times.

At this time, the server will maintain all the resources of this link. If there are a large number of such requests, the resources of the server will be exhausted.

This is a DOS attack.

What if the third message is lost?

The S terminal will start a timer after sending the ACK + SYN message, and confirm that it is lost before receiving the ACK after the timeout trigger, and will try to send again.

Every state in this must be understood, and the interviewer also loves to ask about the state transition above.

Uncle Long also met an interviewer and asked me if I used socket programming? Q. What socket functions have I used?

C-side socket programming code

//C端
#define PORT  8080
#define BUFFER_SIZE 1024
int main(int argc, char **argv)
{
    //定义IPV4的TCP连接的套接字描述符
    int sock_cli = socket(AF_INET,SOCK_STREAM, 0);
    //定义sockaddr_in
    struct sockaddr_in servaddr;
    memset(&servaddr, 0sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = inet_addr(argv[1]);
    servaddr.sin_port = htons(PORT);  
 
    //连接服务器,成功返回0,错误返回-1
    int ret = connect(sock_cli, (struct sockaddr *)&servaddr, sizeof(servaddr));
 
    //客户端将控制台输入的信息发送给服务器端,服务器原样返回信息,阻塞
    while (fgets(sendbuf, sizeof(sendbuf), stdin) != NULL)
    {   
        ret=send(sock_cli, sendbuf, strlen(sendbuf),0); ///发送
        recv(sock_cli, recvbuf, sizeof(recvbuf),0); ///接收
        fputs(recvbuf, stdout);
    }
 
    close(sock_cli); // 关闭连接
    return 0;
}

S-side socket programming code

int main(int argc, char **argv)
{
    //定义IPV4的TCP连接的套接字描述符
    int server_sockfd = socket(AF_INET,SOCK_STREAM, 0);
    //定义sockaddr_in
    struct sockaddr_in server_sockaddr;
    server_sockaddr.sin_family = AF_INET;
    server_sockaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_sockaddr.sin_port = htons(PORT);
 
    //bind成功返回0,出错返回-1
    if(bind(server_sockfd,(struct sockaddr *)&server_sockaddr,sizeof(server_sockaddr))==-1)
 
    //listen成功返回0,出错返回-1,允许同时监听的连接数为QUEUE_SIZE
    if(listen(server_sockfd,QUEUE_SIZE) == -1)
 
    for(;;)
    {
        struct sockaddr_in client_addr;
        socklen_t length = sizeof(client_addr);
        //进程阻塞在accept上,成功返回非负描述字,出错返回-1
        int conn = accept(server_sockfd, (struct sockaddr*)&client_addr,&length);
 
        //处理数据部分
      ...
    }
 
    close(server_sockfd);
    return 0;
}

Why do you need three handshake to establish a link, is it possible to do it twice, but not four times?

Asked this question, what is the interviewer? Asked here for some reason, some are not. Certainly not. The RFC standard is written like this.

I dare not answer in this way. The standard is to establish a link with three handshake, but not four times. If you answer in this way, you will receive it properly. Our interview for classmates is basically over today, you go home and wait for news ...

Uncle Long talked about this problem, why can't it be twice?

If you do not send SYN + ACK for the second time, but just send an acknowledgement message ACK, you will only be able to establish one-way communication, and can not reply. TCP is full-duplex communication, and reliability must be guaranteed.

If the second SYN + ACK is sent, no response is required. There will be three situations

If the first or second handshake fails, the C terminal will repeatedly send the SYN message, waiting for the peer to send an acknowledgment message, and the S terminal will save all the resources of the tcp connection. A large number of such situations will cause S resources to be exhausted.

Second, the second handshake is successful. If S fails to receive the ACK, it will repeatedly send the SYN + ACK message.

3. After the second handshake, the two parties think that the connection is established successfully and they can start communication. If the connection is not really established at this time, the S end will start sending messages, which will cause network congestion.

Why can't it be four times?

Four times is actually possible in principle, that is, the second ACK and SYN are sent in two. It is completely feasible in theory, but TCP is based on the premise of saving network resources.

There is also a piggyback response that does not disassemble the second handshake. After the three handshake, the C side continues to send SYN messages, which is in vain. After the third completion, the link has been established, no matter how many times it is in vain.

What happens if both parties establish a connection at the same time?

TCP establishes a link at the same time
TCP establishes a link at the same time

This is the case where both parties establish links at the same time. The situation is not bad. Anyway, it can be established successfully. This is certain. But pay attention to two points

First, only one full-duplex TCP link is established at this time, not two.

Second, there is no CS between the two parties, and both ends assume two roles at the same time, the client and the server.

Four waves to disconnect

First, look at the whole process and state transition of the four waved hands. The state transition will take a closer look.

Four waves to disconnect
Four waves to disconnect

The C / S mode is still used to explain this process.

The first time: when the application of the C terminal ends the data transmission, it will send a segment with a FIN additional mark to the S terminal (FIN means English finish), then the C terminal enters the FIN_WAIT1 state, and the C terminal cannot send data To the S side.

The second time: The S end will respond to an ACK message after receiving the FIN message, and the S end enters the CLOSE_WAIT state. After entering this state, the S terminal sends the remaining unsent data to the C terminal. After receiving the ACK from the S terminal, the C terminal enters the FIN_WAIT2 state.

At the same time continue to accept other data packets transmitted by the S terminal.

The third time: After the S terminal processes the data to be sent, it will also send a FIN disconnect request, and the S terminal enters the LAST_ACK state.

Fourth time: After receiving the disconnection request from the S terminal, the C terminal starts a timer with a duration of 2MSL (Maximum Segment Time to Live), and sends the last ACK message at the same time.

Why wave four times?

TCP is a full-duplex communication mechanism, and each direction must be closed individually.

The principle of closing the TCP transmission connection is as follows:

When one end completes its data transmission task, it can send a data segment with the FIN field set to 1 to terminate the data transmission in this direction; when the other end receives this FIN data segment, it must notify its application layer that the peer has terminated Data transfer in that direction.

Why can't we use piggyback response mechanism in three-way handshake to reduce one-way handshake?

This is very confusing, but it is not difficult to grasp some details of TCP transmission.

TCP is full-duplex communication. After S receives the disconnection request, it only means that the C terminal will not transmit data to the S terminal, but it does not mean that the S terminal does not transmit data to the C terminal.

If piggybacking is used, the S terminal will not be able to transmit the remaining data to the C terminal.

Why do I need to wait 2MSL after the last ACK?

The network is unreliable, and TCP is a reliable protocol. You must ensure that the last message is delivered before you can disconnect the link, otherwise you will receive the FIN message information on the S side again.

The waiting time of 2MSL is to ensure that it can be resent when the last packet is lost.

Why is the time of 2MSL?

2MSL is the maximum time for a round trip of the message. If it is less than this time, the ACK will be lost, but we have re-sent the ACK before receiving the FIN from the other party.

What if the connection is established but the client suddenly fails?

It's not difficult for TCP to make its own guarantee. TCP has a timer by default. The timer will be set after each request from the client. It is usually set to two hours, and no data has been received after more than two hours.

The server will send a probe message, every 75 seconds thereafter. If there are still no responses after sending 10 probe messages in a row, the server considers that the client has failed, and then closes the connection.

to sum up

The knowledge of three handshakes and four wavers has basically come to an end, and I've come to this. If there is anything I don't understand, you can add me to discuss on WeChat.

There will be an linux command line tool commonly used in network programming later, such as ping, tcpdump, netstat, nc, etc., and a summary article on computer network. This part of the computer network is basically over, if you don't understand it, you can look at the previous article in the official account.

Published 109 original articles · Like 442 · Visits 110,000+

Guess you like

Origin blog.csdn.net/qq_38646470/article/details/105522263