The principle of nat penetration has always been mentioned. Many people will be told to use the UDP punch technology, basically, no one will tell you how to use the TCP protocol to penetrate (or even some people will tell you that the TCP protocol cannot penetrate ). However, we all know that UDP is a connectionless Datagram Protocol, which requires you to maintain the integrity of data packets sent and received by yourself, which often greatly increases the complexity of the program, in addition, some programs must use the TCP protocol for some reason, so that some TCP network program developers often "talk about penetration color change ". So, can TCP be used to achieve penetration? The answer is no: TCP not only achieves NAT penetration, but also is easier than UDP penetration. To learn how to use TCP to penetrate NAT, we should first look at how to use UDP to penetrate NAT. We assume that there are two clients A and B behind two different LAN, and the LAN where AB is located is connected to the Internet through A router. There is a server S on the Internet. At present, AB cannot directly send information with the other party, and AB does not know the real IP address and port of the other party on the Internet, the vro of the LAN where AB is located only allows information sent internally to the outside to pass through. For messages sent by B directly to A's vro, the routing will regard it as "untrusted" and directly discard it. To achieve direct AB communication, you must perform the following three steps: A first connects to the server S on the Internet and sends A message (for A non-connection protocol such as UDP, you can directly send A message through the initial session ), in this way, S obtains the actual terminal (IP address and port number of the message sending) of A on the Internet ). Then B follows the same steps, and S will know the terminals of AB on the Internet (this is "drilling holes "). Then, S tells Client A and client B the actual terminal on the Internet, that is, S tells client B's session terminal, and S tells Client A's session terminal. In this way, after AB knows the actual terminal of the other party, it can directly send messages through the actual terminal (because both parties have previously sent messages to the outside, there is already a message channel on the route that allows data access ). There is no theoretical problem when using UDP to implement the above three steps, because UDP is a connectionless protocol, it allows the socket to communicate "many-to-one" (that is, several sockets with different IP addresses and port numbers send messages to one receiving socket ). However, a problem occurs when you use TCP: under normal circumstances, TCP socket cannot listen on the port that has established a connection and use the local port. In other words, When AB is connected to the server S, S will tell the actual terminal of AB to the other party, and the next step should be to use the actual terminal of the other party for direct connection, however, you will find that the actual terminal of the other party is occupied (that is, the session connecting to the server S occupies the terminal), and The listen and connect cannot be used at the same time. So many people come to the conclusion that TCP cannot achieve NAT penetration. The key to the problem is how to reuse a TCP connection's local terminal. This is not a protocol issue, but an API issue. Fortunately, all mainstream operating systems support a specific TCP socket option-SO_REUSEADDR. This option allows you to bind multiple sockets to the same local terminal. When we create a socket, add the following line: setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, & flag, len); // C ++. setSocketOption (SocketOptionLevel. socket, SocketOptionName. reuseAddress, True) 'This is vb.net. It is easy to know the above knowledge. Next I will talk about the TCP protocol Penetration Process: The machine layout is still the same as the UDP above. Assume that customer A wants to establish a tcp connection with customer B. First, we should establish connections between AB and server S respectively, and S records the actual Internet terminals of AB. Then S sends the actual terminal of the Peer to AB respectively. Then, AB asynchronously calls the connect function from the port used by A and B to S to connect to the other terminal (that is, the terminal notified by S). At the same time, both parties are listening for incoming connections on the same local port (you can also listen for connections first, and connect is better ). Since both parties send a connect request to the other party (assuming that their respective SYN packets have passed through their own NAT), when the other party's connect request reaches the local listening port, the router will think that this request is part of the connect session just now and is licensed, and the local listening port will respond with a SYN-ACK and agree to the connection. In this way, the point-to-point connection through NAT through TCP is successful.