Main part, four-time handshake: Disconnect actually from my point of view without differentiating between the client and server side, either side can call Close (or closesocket) and so on function to start the active termination of a connection. Here, let's talk about the normal situation briefly. When the close function is called to disconnect a connection, the active disconnected One party sends fin (finish message to each other). With previous experience, I think you should understand what I mean when I say fin messages. That is A message segment with the FIN flag bit set. Fin messages may also attach user data, and if the party has data to be sent, the data is attached It is perfectly normal to add this fin message. Then you will see that there are many more such additional messages, such as ACK messages. What we have to grasp The principle is that TCP will certainly be able to achieve maximum efficiency, so you can think of the optimization method, I think TCP will think of. When a passive closed party receives a fin message, it sends an ACK acknowledgement message (you should be familiar with the ACK). Here's A Things to note, because TCP is duplex, that is, you can imagine a pair of TCP connections with two data paths. When sending fin messages , it means that one end of the Send fin cannot send the data, that is, a data path is closed. One end of the passive shutdown is sent After an ACK, the application layer usually detects that the connection is about to be disconnected, and then the passive disconnected application layer calls close to close the connection. I can tell you that once you call close (or closesocket), the fin message is sent on this end. In other words, now passive The closed end also sends Fin to the active shut-off end. Sometimes, the passive shut-off side sends an ACK and fin two messages together. Active The closed side also sends an ACK after the fin is received, and then the entire connection is closed (in fact not completely shut down, just shutting down the messages that need to be exchanged for sending Finished), four handshake completed. As you can see, because the passive shut-off side may send the ACK and fin together, this is not A strict four-time handshake---four message segments. In the previous article, I never mentioned the state transition of TCP. Here I am still hesitating whether to take out the general-purpose picture, However, here I only give the state transition diagram when disconnected, excerpt from <the TCP/IP guide>: Give a windump message when a normal shutdown: 14:00:38.819856 IP cd-zhangmin.1748>220.181.37.55.80:f 1:1 (0) Ack 1 win 65535 14:00:38.863989 IP 220.181.37.55.80> cd-zhangmin.1748:f 1:1 (0) Ack 2 win 2920 14:00:38.864412 IP cd-zhangmin.1748>220.181.37.55.80:. ACK 2 win65535 Additional details: With regard to the above four handshakes, I add the following details: 1. By default (without changing the socket option), when you call Close (or closesocket, the following says close is no longer repeated), if There is also data in the send buffer, and TCP will continue to send the data out. 2. Sending fin simply means that the end cannot continue sending the data (the application layer can no longer call send), but may also receive data.
3. How the application layer knows to close the peer. Typically, in the simplest blocking model, when you call recv, if you return 0, it means that the peer Shut down. At this point the usual practice is to also call Close, then the TCP layer sends fin and continues to complete four handshake. If you do not call Close, the peer will be in the Fin_wait_2 state, and the local side will be in the close_wait state. This can write code to try.
4. In many cases, the TCP connection will be disconnected automatically by the TCP layer, for example, you have CTRL + C to terminate your program, the TCP connection is still normal shutdown You can write code to try it.
Special time_wait states: From the above TCP connection Shutdown state transition diagram can be seen, the active shutdown of the party after sending out the other Fin message confirmation (ACK) message, Will enter the TIME_WAIT state. The TIME_WAIT state is also known as the 2MSL state. What is 2MSL. The MSL is maximum Segment Lifetime, which is the maximum lifetime of the message, quoting <TCP/IP in detail >: " It (MSL) is the maximum time that any segment of a message is discarded before it is inside the network. "Well, 2MSL is twice times that time. Actually, I don't think so. It is necessary to understand the exact meaning of this MSL, and what you need to understand is that when the TCP connection completes the exchange of four pieces of message, the active shutdown One side will continue to wait for a certain amount of time (2-4 minutes) Even if both ends of the application end. You can write code to try it and then use Netstat to view it. Why 2MSL is required. According to <TCP/IP > and <the TCP/IP guide>, there are two reasons: One is to ensure that the ACK sent is sent to the other party successfully. I think it might be sent through a timeout timer. This is hard to use. The code demonstrates. Second, the message may be confused, meaning that other times the connection may be used as the connection. Direct reference <the TCP/IP guide> Statement: The second is to provide a "buffering period" between the end of this connection and any subsequent ones. If not for this period, it's possible that packets from different Connections could be mixed, creating confusion. The impact of the TIME_WAIT state: When one end of a connection is in the TIME_WAIT state, the connection will no longer be used. In fact, for us to be more realistic Yes, this port will no longer be used. When a port is in the TIME_WAIT state (which should actually be the connection), this means that the TCP The connection is not disconnected (completely disconnected), so if you bind this port, it will fail. For the server, if the server suddenly crash out, it will not be able to restart within 2MSL, because bind will fail. Solve this One way to do this is to set the socket's SO_REUSEADDR option. This option means that you can reuse an address. For the Time_wait episode: When a TCP connection is established, the server will continue to listen on the original port and use this port to communicate with the client. and the client default A random port is used to communicate with the server-side listening port. Sometimes, for server-side security, we need to Authentication, which is a client that qualifies a specific port on an IP. The client can use bind to use a specific port. For the server side, when the SO_REUSEADDR option is set, it can be started within 2MSL and listen successful. But for the client, when the When you use BIND and set SO_REUSEADDR, if you start within 2MSL, bind succeeds, but connect fails on the Windows platform. There is no such problem on Linux. (My experimental platform: WinXP, ubuntu7.10) </ |