Socket programming-the server encounters a broken pipe crash

Source: Internet
Author: User

I wrote a server program. During testing in Linux, I always exit inexplicably. Finally, I tracked the exit caused by a write call. I used GDB to execute the program and prompted "Broken pipe" when exiting ".

Finally, the problem is determined that a socket that has been closed on the peer end is called twice for write. The second request will generate a sigpipe signal, which ends the process by default.

The specific analysis can be combined with TCP's "Four handshakes" to close. TCP is a full-duplex channel. It can be seen as two ticket channels. The two ends of the TCP connection are each responsible for one. when the peer calls close, although the intention is to close the entire two channels, the local end only receives the fin package. according to the semantics of the TCP protocol, the peer only closes the ticket channel in charge of it and can continue to receive data. that is to say, due to the restrictions of the TCP protocol, an endpoint cannot know whether the socket of the Peer side calls close or shutdown.

Call the read method for a socket that has received the FIN packet. If the receiving buffer is empty, 0 is returned. This is often said to indicate that the connection is closed. but when you call the write Method for it for the first time, if there is no problem with the sending buffer, the correct write (sending) will be returned ). however, the sent packets will cause the Peer to send the RST packet, because the socket at the peer end has already called close and is completely closed, neither sending nor receiving data. therefore, the second call to the write method (assuming that after receiving the RST) generates a sigpipe signal, causing the process to exit.

To prevent the process from exiting, you can capture the sigpipe signal or ignore it and set the sig_ign signal processing function for it:

Signal (sigpipe, sig_ign );

In this way, when the second write method is called,-1 will be returned, and errno is set to sigpipe. The program will know that the Peer has been closed.

PS: in Linux, sigalrm seems to be offset by 1 ms every second. However, in windows, sigalrm is completely tested on time, with no difference of 1 ms.

Of course, there are other methods to deal with sigpipe.

Set the current socket to not generate sigpipe during write operations.

?
12 int

set = 1;
setsockopt(sd,
SOL_SOCKET, SO_NOSIGPIPE, (
void

*)&set,
sizeof(int));

In some cases, we do not need a global sigpipe handler. But it is said that this is not common and there is no corresponding definition in Linux-but I passed the test on Mac.

From http://blog.csdn.net/mustanglau/article/details/4485491

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.