For a TCP connection, there are generally 2 ways to turn it off in the C language:
Close (SOCK_FD);
or
shutdown (sock_fd, ...);
In most cases the effect of these 2 methods is no different and can be used interchangeably. Except: Close () is an operation on file shutdown () is an operation on the socket
A socket in a UNIX system is a file, but the file is not necessarily a socket;
So there is a difference in the behavior of Close () and shutdown () after entering the system call and before reaching the protocol layer (the Fin packet is issued).
After reaching the protocol layer, close () and shutdown () are no different. give a few chestnuts a demonstration of the difference between close () and shutdown ()
The following examples illustrate the behavior differences between close () and shutdown () in multithreaded concurrency, and we assume that the scenario is: SOCK_FD is a socket in blocking mode. The recv () that thread-1 is blocking SOCK_FD is not returned. Thread-2 calls Close () or shutdown () directly to SOCK_FD. Do not consider linger. Chestnut 1:socket blocked on recv (), call Close ()
Close a waiting recv () | | thread-1 | thread-2 | tcpdump | |
| | Recv (SOCK_FD |
| | <unfinished ...> |
| 1| |
Close (SOCK_FD) = 0 | | | | Some Data Arrived | | | After close () 2| | | < seq 1:36 ... length 35 | | | > Ack 36 ... | Data was received. |
| 3| recv resumed>) = 35 |
| 4| | | > FIN Sent | | | < ack of FIN received | | | ...
| Can ' t be used no more |
| 5v recv (SOCK_FD) =-1 | |
In the example above:
(1) The thread-2 call Close () succeeds immediately, when recv () is still using SOCK_FD.
There are 1 other threads thread-1 are using sock_fd here, so just mark this sock_fd to be closed. The socket does not really close. The recv () also continues to be in a blocking read state.
(2) after close (), some data is arrived and recv can be read and returned.
(3) recv () received the data, the correct exit.
(4) Rece () ends the call, releasing the reference to the socket, at which point the bottom begins to shut down the socket process.
(5) calling recv () again will get an error.
As you can see, close () does not immediately disconnect the socket or interrupt the waiting recv (). Chestnut 2:socket blocked on recv (), call shutdown ()
Shutdown a waiting recv ()
time
|
| Thread-1 | thread-2 | tcpdump | | |
| Recv (sock_fd | | | <unfinished ...> | |
1| | Shutdown (SOCK_FD) = 0 | > Fin Sent | | | < ack of fin received | | Woken up by shutdown () | |
| No errno set | |
2| recv resumed>) = 0 | |
V | |
In the example above:
(1) Thread-1 is still waiting for SOCK_FD, thread-2 call shutdown (), immediately start shutting down the socket process, fat fin packets.
The Tcp_shutdown in the kernel then invokes the thread-1 on the recv () in the Sock_def_wakeup wake blocking.
(2) the recv () blocked thread is awakened to wait and returns immediately. The return code is 0, which means the socket is closed.
As you can see, the shutdown () and close () are different, and the socket connection is immediately closed and the waiting recv () is awakened.
Code for the above 2 examples
Close-or-shutdown-recv Chestnut 3:socket blocking on accept (), calling shutdown ()
Similarly, shutdown () is invoked on the socket blocking on accept (), and accept is also awakened:
Shutdown a waiting accept ()
time
|
| Thread-1 |
thread-2 | | Accept (sock_fd |
| <unfinished ...> |
1| | Shutdown (SOCK_FD) = 0
| |
| Woken up by shutdown () |
| errno set to Einva |
2| Accept resumed>) =-1 | | |
V |
(1) Thread-1 is still waiting for SOCK_FD, thread-2 call shutdown (), immediately start shutting down the socket process, fat fin packets.
The Tcp_shutdown in the kernel then invokes the thread-1 on the Accept () in the Sock_def_wakeup wake blocking.
(2) The thread that is blocked on the accept () is awakened and returned immediately.
The return code is -1,errno set to Einva.
Here if Thread-2 calls Close (), the accept will not be awakened, and if the subsequent request connect comes in, it can be properly accepted and returned. Conclusions
Shutdown () close the socket immediately;
And can be used to wake up the waiting thread;
Close () does not necessarily immediately shut down the socket (if someone references it, wait until the reference is lifted);
The wait thread is not awakened.
Most Web applications now use nonblocking sockets and event models such as Epoll, because nonblocking does not have thread blocking, and the behavior differences mentioned above are not reflected. Note
This article is not reproduced in full text, only for the partial reprint as a note. Transferred from
Socket off: Difference between close () and shutdown ()