The recv blocked after the Linux close socket is not returned immediately

Source: Internet
Author: User
Tags ack

A strange phenomenon was found in the development of a program based on rtmp chat.

Under Windows, when we perform closesocket operations, the blocked recv immediately returns-1.

And under Linux, when we do the close operation, the blocked Recv will not return immediately. Later on the Internet a search found a lot of things like this phenomenon, the general meaning should be

When the socket passive is close, it enters the "close_wait (passive closed side)" case.

The workaround is to call before you close:

Shutdown (socket, shut_rdwr);

is to turn off the read and write function of the socket.

------------------------------------------------------

Here are some explanations for such phenomena as "close_wait":

active shut-off and passive side experience Status:
fin_wait_1 (active close side): When the socket is in the established state, it wants to turn off the active
a fin message is sent to the other side, and the socket enters the
fin_wait_1 status. And when the other person responds to the ACK message, it enters the fin_wait_2 state,
fin_wait_2 (active close side): This state has been explained in detail above, in fact fin_wait_2
State of the socket, indicating a half connection, that is, one side requires close connection, but also tell the other side, I temporarily have some data to send to you, and then close the connection.
time_wait (active close Party): Indicates receipt of the other's fin message, and sends out an ACK message
just wait for 2MSL (twice times the maximum survival time) to return to the closed available state.
close_wait (passive closed side): The meaning of this state is actually expressed in waiting to close. When each other
close a socket and send fin messages to yourself, and your system will undoubtedly respond to
an ACK message is sent to the other side, at which point the close_wait state is entered. Next thing you really need to think about is whether you still have the data sent to the
side, if not, then you can close the socket, send fin messages to each other, that is, close the connection. So what you need to accomplish in the close_wait state is waiting for you to close the connection.
last_ack (passive closed side): It is the passive off party after sending the fin message and finally waiting for the other party's
ACK messages. When an ACK message is received, it can be entered into the closed available state

-------------------------------------------------------------------

Here are some instructions for the socket's close and shutdown:

There are two ways to close the connection in a Linux socket , namely shutdown and close, first look at the definition of shutdown

#include <sys/socket.h>

int shutdown (int sockfd,int how);

How there are three different ways to be

SHUT_RD (0): Turn off read function on SOCKFD, this option will not allow SOCKFD to read.

SHUT_WR (1): Turn off SOCKFD write function, this option will not allow SOCKFD to write.

Shut_rdwr (2): Turn off the read and write function of SOCKFD.

Success returns 0, error return-1, error code ERRNO:EBADF means SOCKFD is not a valid descriptor; Enotconn means SOCKFD is not connected; Enotsock means SOCKFD is a file Descriptor instead of the socket descriptor.

The definition of close is as follows:

#include <unistd.h>

int close (int fd);

Turn off read and write.

Success returns 0, error return-1, error code ERRNO:EBADF indicates that FD is not a valid descriptor; Eintr indicates that the close function is interrupted by the signal; Eio represents an IO error.

The following excerpt from the online paragraph to illustrate the difference between the two:

Close-----Closes the socket ID for this process, but the link is still open, and other processes with this socket ID can use this link to read or write the socket ID

shutdown--the socket link, read the time may be detective to the EOF Terminator, when writing may receive a sigpipe signal, this signal may be until

Socket buffer is filled before receiving, shutdown also has a closed mode parameter, 0 can not read, 1 can not write, 2 read and write can not.

Shutdown in a multi-process socket, close uses

When all data operations are finished, you can call the close () function to release the socket, thereby stopping any data manipulation on that socket:

Close (SOCKFD);

You can also call the shutdown () function to close the socket. This function allows you to stop data transfer in one direction only, while the data transfer in one Direction

Continued. If you can close a socket's write operation and allow the data to continue to be accepted on that socket until all data is read.

int shutdown (int sockfd,int how);

SOCKFD is the descriptor of the socket that needs to be closed. Parameter how allows you to choose the following methods for shutdown operations:

SHUT_RD: Closes the read end of the connection. That is, the socket no longer accepts data, and any data currently in the socket accept buffer will be discarded. The process will not be able to

The socket emits any read operations. Any data received after the call to the TCP socket will be acknowledged and silently discarded.

SHUT_WR: Closing the write end of the connection, the process cannot write to this socket

Shut_rdwr: equivalent to calling shutdown two times: first with SHUT_RD, then SHUT_WR

Use close to abort a connection, but it only reduces the reference number of the descriptor, does not close the connection directly, and closes the connection only if the descriptor has a reference number of 0 o'clock.

Shutdown can close the descriptor directly, regardless of the descriptor reference number, you can choose to abort One direction of the connection.

Attention:

1>. If more than one process shares a socket, close is called once, and the count is reduced by 1 until the count is 0 o'clock, which means that the used process calls close and the socket is freed.

2>. In a multi-process process, if a process is shutdown (SFD, shut_rdwr), other processes will not be able to communicate. If a process close (SFD) will not affect other processes. You have to understand the usage of reference counting. Have a better understanding of kernel programming knowledge.

More notes on Close and shutdown

1>: As long as the read buffer in the TCP stack has unread (read) data, the call to close will send the RST directly to the peer.
2>: Shutdown does not have a relationship with the socket descriptor, even if the call to shutdown (FD, SHUT_RDWR) does not close the FD, and eventually close (FD) is required.
3>: Shutdown (FD, SHUT_RD) can be considered an empty operation, since shutdown can continue to read data from the socket, which may require further confirmation.
4>: Write the socket descriptor after the fin package has been sent raises epipe/sigpipe.
5>: When there are multiple socket descriptors pointing to the same socket object, calling close first decrements the reference count of the object, and the count is 0 o'clock to send the FIN packet end TCP connection. Shutdown, a FIN packet is sent as long as it is called in Shut_wr/shut_rdwr mode.


6>: So_linger with Close, when the So_linger option is on but the timeout value is 0 o'clock, call close to send the RST directly (this avoids entering the time_wait state, but destroys the way the TCP protocol works), So_ Linger has no effect on shutdown.


7>: The emergence of a RST on a TCP connection is not directly related to the subsequent possible time_wait state, and the active fin outsourcing is bound to enter the TIME_WAIT state unless FIN is sent directly to end the connection by sending the RST.

-----------------------------------------------------------------------------

The following is a summary of the network discussion materials related to the topic:

http://bbs.csdn.net/topics/350147238

http://bbs.csdn.net/topics/350050711

http://blog.csdn.net/helpxs/article/details/6661951

The recv blocked after the Linux close socket is not returned immediately

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.