When it comes to the TCP protocol, anyone who has seen a little bit can easily say three handshakes and four breaks, and then a little bit of it will be able to put each state (Sync_sent, close_wait ...). etc) can be back out,
and said socket programming, basically wrote the network programming person will be familiar with those several standard api:socket, connect, listen, accept ... such as
However, I bet few people understand the relationship between the TCP state and the socket programming API . Don't believe me? Take a look at some of the following questions you know:
1) When will the client be able to connect to the server side, after the server has called bind or after listen or after accept?
2) What happens when the fin_wait_2 state is present
。。。。。。。。。。。。。。。。。。。。。
This week to break the spirit of the sand pot and the spirit of seeking truth from facts, I wrote some scripts in Python script to test these situations, you will be very enjoyable after reading, the TCP protocol and socket programming understanding of the upper floor.
Note: The following tests are tested on the Linux (2.6.18) platform with the Python (2.7) script, the other platforms are not tested, and are interested to test them yourself.
"Connection process testing and validation"
1th Case: Client call Connect,server just call socket + bind, no call listen
Tcpdump grab bag as follows:
Grab packet results show: Server side directly reply to the RST package
At this time using the netstat or SS command to view, either client or server, can not find the connection
2nd case: Client call Connect,server socket + bind + Listen
Tcpdump grab bag as follows:
Clutch results Display: Three handshake complete
Use the SS tool to view, both client and server display Estab
[[Email protected] ~]$ SS -t-n | grep 50000ESTAB 0 0 10.1.73.45:55354
3rd case: Client call to connect + send,server call Socket + bind + Listen + accept + recv + send
Tcpdump grab bag as follows:
Clutch results show: Three handshake complete, and both can send and receive data
Use the SS tool to view, both client and server display Estab
[[Email protected] ~]$ SS -t-n | grep 50000ESTAB 0 0 10.1.73.45:41363
"Connection Process Summary"
1) You can see that the client side calls connect only after the server side listen, otherwise it will return the RST response to deny the connection
2) client and server can invoke IO operations such as recv and send only after accept
3) The socket API call error does not cause the client to appear syn_sent state, then only the network device drops (router, firewall) will cause the sync_sent state
"Disconnection process test and summary"
1th Scenario: Client calls Close, but server does not call close
Tcpdump grab bag as follows:
Packet Capture results: Client sends fin packet, server side answers ACK packet
Using the SS tool to view, the client displays the Fin_wait_2 status:
[[Email protected] ~]$ SS -t-n | grep "10.1.73.76:50000" Fin-wait-2 0 0 10.1.73.45:47630 10.1.73.76:50000
Server Display close-wait status
[[Email protected]_test ~]$ SS -t-n | grep 50000close-wait 1 0 10.1.73.76:50000
and one notable phenomenon is that the client hasnot been connected for some time, and the server connection has been in close_wait state
The reason is that there is a parameter in the kernel of the Linux system that can control Fin_wait_2 time: Tcp_fin_timeout
2nd scenario: Client calls Close,server call Close
Tcpdump grab bag as follows:
Clutch results show: familiar with the four-time disconnection
Use SS tool to view, client display time-wait status
[Email protected] ipv4]$ ss-a-n | grep 50000time-wait 0 0 10.1.73.45:39751
the server side uses the SS tool to see that the connection has not been seen
3rd Scenario: Server side is killed
Tcpdump grab bag as follows:
Clutch results show: familiar with the four-time disconnection
Well, how could it be the same as the normal server close? the answer lies in the implementation of the operating system:
The close function does not in itself cause the TCP stack to send the fin packet immediately, but only the reference count of the socket file is reduced by 1, and when the reference count of the socket file becomes 0, the operating system automatically shuts down the TCP connection before the fin packet is sent.
This is also a point of special attention to multi-process programming, the parent process must be the socket file descriptor close, or run a period of time may appear after operating system prompts too many open files
4th Scenario: Client-side invoke shutdown operation
Shutdown operation has three kinds of closure methods: Shut_rd, SHUT_WR, Shut_rdwr, respectively, after testing to find interesting phenomenon.
1) If it is shut_rd, then tcpdump catch packet found not sent any package;
2) If it is SHUT_RD or SHUT_RDWR, the client sends a FIN packet to the server,
If the server receives a close operation, the server sends fin to the client and the final connection is closed.
The SHUT_WR or Shut_rdwr capture package displays as follows:
Using the SS command to view, the client displays as follows:
[Email protected] ~]$ Ss-a | grep 50000time-wait 0 0 10.1.73.45:45641
The server shows that the connection has been closed.
For a detailed explanation of shutdown, refer to: http://www.gnu.org/software/libc/manual/html_node/Closing-a-Socket.html
Summarize treatment of SHUT_RD:
1) client side no longer receives data, if new data arrives, direct discard (reject)
2) did not send any TCP packets, so the server side does not know this state, server side can continue to send data, but because of 1) reason, hair also white hair
Summarize the treatment of SHUT_WR or shut_rdwr:
1) Stop transmitting the data (no more calls to the write operation), Discard unsent data in the buffer (write is called but the underlying TCP stack is not yet sent)
2) Stop waiting for a confirmation message for the sent data, sent unconfirmed data no longer re-sent
"Disconnection Process Summary"
1) Close only reduces the reference count of the socket file, and when the count is reduced to 0, the operating system performs a TCP disconnection operation
2) client side close after server side does not close, will cause the client side connection status is Fin_wait_2,server end connection state is close_wait
Normal programming is certainly not handled in this way, typically in exception handling jumps (C++/java, etc.) resulting in no close, or an entire system exception resulting in no close (for example, JVM memory appearing out of a memory error)
3) Shutdown processing logic is more complex, non-special circumstances do not mess with, it is easy to problem
4) After the process exits the operating system will automatically recycle the socket, initiating the TCP shutdown process operation
TCP three-time handshake and four-time disconnection in-depth analysis: Connection status and Socket API relationships