Socket in Linux Network Programming (10): difference between shutdown and close Functions

Source: Internet
Author: User

If the server and client have established a connection, the server calls close and sends the fin segment to the client (in fact, it may not necessarily send the fin segment, which will be discussed later ), at this time, the server can no longer send and receive data through the socket. At this time, the client calls read. If the received fin segment returns 0, but the client can still write data to the server at this time, the write call is only responsible for handing over the data to the TCP sending buffer to return a successful result, so there is no error. The server replies to an rst segment after receiving the data, indicating that the server cannot receive the data and the connection is reset, after the client receives the RST segment, it cannot immediately notify the application layer. It only saves the status on the TCP protocol layer. If the client calls write again to send data to the server, the TCP protocol layer is already in the RST state, so the data is not sent, but a sigpipe signal is sent to the application layer, the default processing action of the sigpipe signal is to terminate the program.


Sometimes the code needs to call write multiple times in a row, and it may be too late to call read to find that the other party has closed the connection and the sigpipe signal is terminated, in this case, you need to call sigaction during initialization to process the sigpipe signal. We usually ignore this signal. Signal (sigpipe, sig_ign); If the sigpipe signal does not cause the process to exit abnormally, write returns-1 and errno is epipe.


# Include <unistd. h>
Int close (int fd );

Close closes two data transmission directions.


# Include <sys/socket. h>
Int Shutdown (INT sockfd, int how );

Shutdown can choose to close either one direction or both directions. Shutdown how = 1 or how = 2 (shut_wr or shut_rdwr ), ensure that the Peer receives an EOF character (that is, a fin segment is sent), regardless of whether other processes have enabled this socket. However, close cannot guarantee that only when the reference count of a sockfd is 0 will close send the fin segment. Otherwise, it only reduces the reference count by 1. That is to say, only when all processes (maybe multiple Fork sub-processes open this socket) Close this socket.
To send the fin segment.

Therefore, if shutdown how = 1 is called, it means that writing to a socket that has received the fin is allowed. Receiving the fin segment only means that the other party no longer sends data, however, the other party can still read data, allowing the other party to continue reading the remaining data in the buffer.


Next we will use shutdown to modify the client program. Based on the client program modified by the Select function, we will modify a small part of it:

C ++ code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
If (fd_isset (fd_stdin, & rset ))
{

If (fgets (sendbuf, sizeof (sendbuf), stdin) = NULL)
{
Stdineof = 1; // indicates that the input is complete.
/* Close the sock write end and receive data. Add a fin segment at the end of the sock buffer */
Shutdown (sock, shut_wr );
}
Else
{
Writen (sock, sendbuf, strlen (sendbuf ));
Memset (sendbuf, 0, sizeof (sendbuf ));

}
}

To test the expected results, we need to sleep (4) after the first line of code of the server-side program modified by the Select function, that is, before writen ); the purpose is to send data after receiving data from the client and then send the data after 4 s of sleep.

Run the server-side program first, then run the client program, enter the standard input in the client, and quickly enter two lines: AAAAA \ n bbbbb \ n. Then press Ctrl + D, that is, fgets will return null, then, call shutdown to close the write end. Although the server side sends data only after the delay, the client write end is closed, but the data returned by the reply can still be read, the server finally obtains a fin segment, read returns 0, print the output client close, and close (conn). After the client reads the data sent back by the server, if the read operation returns 0 again, the server is printed.
Connect close, break exit loop, and the process exits smoothly. From the output below, we can also see that because of the delay, a row is not shot back as before when a row is fired.

Simba @ Ubuntu :~ /Documents/code/linux_programming/UNP/socket $./echoser_select
Recv connect IP = 127.0.0.1 Port = 54010
Fdsgfgd
Gfedg
Client close

...........................

Simba @ Ubuntu :~ /Documents/code/linux_programming/UNP/socket $./echocli_select_shutdown
Local IP = Wagner. 0.0.1 Port = 54010
Fdsgfgd
Gfedg
Fdsgfgd
Gfedg
Server connect close


If we change the shutdown in the client program to close, when the server sends data to the client after the delay, both the read and write ends of the client are closed, the first time AAAAA is sent, an rst segment is returned. As mentioned above, sending bbbbb again directly generates the sigpipe signal. The process is terminated by default, but because we have set the sigpipe signal to be ignored, therefore, the process on the server side will not be terminated, but the client will also make an error, because it returns to the beginning of the while loop, when the select blocking waits, it is found that the read end of the socket has been closed, so you can no longer care about the readable event, select returns-1 with the error code:
Ebadf: Bad file descriptor.


Refer:

Linux C Programming one-stop learning

Chapter 1 TCP/IP details

UNP

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.