Sockets, TCP Status, and Recording System

I work with a simple server that sends a heartbeat packet to the client every 30 seconds, which then confirms a heartbeat with a heartbeat response packet. When I brutally shut down the server by sending it SIGKILL, SIGSEGV, the client detects this using the select () and read () system calls quite easily. Then I started wondering what would happen when you do this just before the client writes down their response response packet, so I put a 20 second sleep in the client code and, on average, killed the server, but found that the message was on the side the client still succeeds. An attempt at a second recording immediately triggered the expected SIGPIPE signal and recorded the returned EPIPE. As far as I can tell, this is normal behavior, however, only out of curiosity did I print out the tcp status on the client side. It turned out:

  • TCP_ESTABLISHED - before sending the SIGKILL server.
  • TCP_CLOSE_WAIT - after SIGKILL on the server side before recording on the client side.
  • TCP_CLOSE - after the first and second write attempts.

So my questions are:

  • Why does the first record not call SIGPIPE and return EPIPE?
  • Can I conclude that if the TCP state is TCP_CLOSE after the first record, that the connection to the server is not working or do I need to resend the data again to make sure?

A diagram of what happens when I understand this at the moment:

                       server                               client

          [ESTABLISHED]  |                                     | [ESTABLISHED] 
 SIGKILL or close () --> |                                     |  
          [FIN_WAIT_1]   |------------FIN M------------------->| [CLOSE_WAIT] 
                         |                                     |            ---\
          [FIN_WAIT_2]   |<-----------ACK M+1------------------|               |  
                         |                                     |               |   a read performed after a
          [TIME_WAIT]    |<-----------FIN N--------------------| [LAST_ACK?]   |-- serverside SIGKILL returns 0
                         |                                     |               |   but write succeeds
                         |------------ACK N+1----------------->| [CLOSE]       |
                         |                                     |            ---/
                         |                                     | 
                         |                                     |            ---\
                         |                                     | [CLOSE]       |   After the first write returns
                         |                                     |               |   the TCP/IP state is CLOSED 
                         |                                     | [CLOSE]       |   but even so only the a second 
                         |                                     |               |   returns EPIPE and raises SIGPIPE.
                         |                                     | [CLOSE]       |   
                         |                                     |               v 
+4
source share
1 answer

Why does the first record not raise SIGPIPE and return EPIPE?

TCP . . TCP . , send/sendmsg/write , , .

, ​​ close , , FIN, TCP_CLOSE_WAIT. , , .

, RST, . TCP_CLOSE.

, TCP TCP_CLOSE , , ?

TCP_CLOSE - TCP. , , , , .

+3

Source: https://habr.com/ru/post/1547935/


All Articles