When closing the tcp connection, sometimes send FIN and sometimes RST

Use http to send the same packet, read the data after 20 seconds of sleep, htpp sets a timeout of 1s, and the socket will be closed after the timeout, but sometimes RST is sent, sometimes FIN is sent, as shown in the figure below:

 

Later, I googled it and found that the data in the receiving buffer of tcp reaches the user mode, and there are three queues in the middle:

  • The receive queue is the real receive queue. After the TCP data packet received by the operating system is checked and processed, it will be stored in this queue.
  • backlogIt is the "standby queue". When the socket is in the context of the user process (that is, the user is making a system call to the socket, such as recv), the operating system will save the data packet to the backlogqueue when it receives the data packet  , and then return directly.
  • prequeueIt is a "prestored queue". When the socket is not being used by the user process, that is, the user process calls the read or recv system call, but enters the sleep state, the operating system directly saves the received message in  prequeueit, and then returns.

Normally, the TCP message receiving process involves three queues:

  1. backlog:  sk->sk_backlog
  2. prequeue: tp->ucopy.prequeue
  3. receive:        sk->sk_receive_queue

After the go program calls send(), recv() is in a blocking state, so the data will enter the Prequeue. At this time, because the timeout period expires, recv() is not executed.

Sometimes a message can all enter the Prequeue, then there is no data in the buffer, so when it is closed, FIN is sent

Sometimes it is not possible to enter the Prequeue completely. At this time, there is still some data in the buffer, so when it is closed, RST is sent; 

reference:

https://ylgrgyq.github.io/2017/08/01/linux-receive-packet-3/

https://www.cnblogs.com/chenny7/p/5067826.html

Guess you like

Origin blog.csdn.net/zgb40302/article/details/111213559