. Net (C #): Use UPnP to penetrate NAT to make the Intranet interface visible to the Internet

Source: Internet
Author: User

After writing object 672, a critical problem of the software is exposed. If both the server and client are in the Intranet environment, that is, both parties use NAT to access the Internet, in this case, the client cannot directly communicate with the server.

The solution can be:

1: deploy the server in a public network without Nat.

2: Use common Nat penetration methods, such as UDP injection or STUN Protocol. However, these methods require another known server deployed in the public network environment.

3: The solution discussed in this article is that you do not need to deploy servers in any public network environment, and bind Intranet interfaces to public network interfaces through the UPnP protocol supported by the vro.

One of the major advantages of UPnP is that it does not need to send UDP packets to external interfaces to inform Nat of the bound public network interfaces as UDP holes. In addition, for symmetric Nat, UDP holes are invalid. Once the UPnP is set successfully, the Intranet interface is completely exposed to the Internet using the bound public network interface.

 

The demo program runs like this:

 

Specific process:

1. output the Host Name and Intranet IP address of the user.

2. Use UPnP to bind the Intranet IP address and internal port number to an external port number.

3. Obtain a public IP address from an external website through HTTP.

4. Create a TCP socket server in the intranet.

5. Create another TCP socket client and try to connect the obtained public IP address to the external port bound to UPnP.

6. If there is no problem, it will connect to the server and receive a response!

 

To use the Windows UPnP component in the. NET environment, you must reference the natupnp 1.0 Type Library in the current project. This is a com class library.

The following code analyzes the source code one by one. The source code is intended to be added to the following namespace:

Using system. net;

Using system. net. Sockets;

Using system. Text. regularexpressions; // obtain the regular expression of the IP address.

Using system. Threading. tasks; // task

Using system. IO; // streamreader is used to read Server Information

Using natupnplib; // Windows UPnP COM Component

 

First, output the Local Machine (that is, the Intranet Interface Information). This is simple:

// Obtain the Host Name

VaR name = DNS. gethostname ();

Console. writeline ("User:" + name );

// Resolve the IP address from the current host name and filter the IPv4 address as the Intranet IP address of the local machine.

VaR IPv4 = DNS. gethostentry (name). Addresslist. Where (I => I. addressfamily = addressfamily. InterNetwork). firstordefault ();

Console. writeline ("intranet IP:" + IPv4 );

 

Next, set UPnP. First, you need to initialize the upnpnat type (which is an interface, but directs the execution to the upnpnatclass type through the coclass feature), and then add or delete UPnP bindings through the staticportmappingcollection of upnpnat. Note that if no vro or the UPnP of the vro is enabled, the staticportmappingcollection attribute may return null.

 

The Code is as follows:

Console. writeline ("set UPnP ");

// UPnP binding information

VaR eport = 8733;

VaR iport = 8733;

VaR description = "mgen test ";

 

// Create a com type

VaR upnpnat = new upnpnat ();

VaR mappings = upnpnat. staticportmappingcollection;

 

// Error Determination

If (mappings = NULL)

{

Console. writeline ("No vro is detected, or the vro does not support UPnP. ");

Return;

}

 

// Add the previous IPv4 variable (intranet IP address), internal port, and external Port

Mappings. Add (eport, "TCP", iport, ipv4.tostring (), true, description );

 

Console. writeline ("external port: {0}", eport );

Console. writeline ("internal port: {0}", iport );

 

If the router is successful, you can view the data in the router's UPnP options:

 

After setting UPnP, start to get the Internet IP address, you can through this URL (http://checkip.dyndns.org /). In this case, you only need to send an http get request, and then extract the IP address in the returned html. We use regular expressions to extract the IP address.

The Code is as follows:

// Internet IP address variable

String EIP;

// Regular

VaR RegEx = @ "\ B \ D {1, 3} \. \ D {1, 3} \. \ D {1, 3} \. \ D {1, 3} \ B ";

Using (VAR WebClient = new WebClient ())

{

VaR rawres = WebClient. downloadstring ("http://checkip.dyndns.org /");

EIP = RegEx. Match (rawres, RegEx). value;

}

 

Console. writeline ("Internet IP:" + EIP );

 

OK. At this time (if everything goes well), everything is ready. We have: Intranet IP address, internal port, Internet IP address, and external port. Then we can test a TCP connection.

 

Directly create a TCP server, which indicates the server under Nat. Note that the port number must be bound to the internal port set by UPnP.

Code:

// Servers under Nat

VaR socket = new socket (addressfamily. InterNetwork, sockettype. Stream, protocoltype. TCP );

// Bind the Intranet IP address and internal port

Socket. BIND (New ipendpoint (IPv4, iport ));

Socket. Listen (1 );

 

// Run the client socket in another thread

Task. Run () =>

{

Task. delay( 1000). Wait ();

Clientsocket (EIP, eport );

});

 

// Successful connection

VaR client = socket. Accept ();

// The server sends messages to the client

Client. Send (encoding. Unicode. getbytes ("=== welcome to the mgen server! = "+ Environment. newline ));

 

Console. readkey (false );

 

The clientsocket method above is executed by the client's socket connection. Note that the TCP protocol does not retain the data boundary. Therefore, the server adds an environment when sending messages. newline), and then when the client accepts data, use the nested combination of socket-> networkstream-> streamreader, and finally read the data by the Readline of streamreader. This ensures that the final line break is read.

 

Code for executing the clientsocket method:

// The IP and port parameters are public IP addresses and external ports in UPNP.

Static void clientsocket (string IP, int port)

{

Try

{

Console. writeline ("Creating a client TCP connection ");

VaR socket = new socket (addressfamily. InterNetwork, sockettype. Stream, protocoltype. TCP );

Socket. Connect (New ipendpoint (IPaddress. parse (IP), Port ));

Using (var ns = new networkstream (socket ))

Using (VAR sr = new streamreader (NS, encoding. Unicode ))

{

Console. writeline ("response received from the server :");

Console. writeline (Sr. Readline ());

}

}

Catch (exception ex)

{

Console. writeline (ex. Message );

}

}

OK.

 

Source code download
Download Page
Note: the link is the Microsoft SkyDrive page. When downloading, use a browser to download it directly. Some download tools may not be available for downloading.
Source code environment: Microsoft Visual Studio express 2012 for Windows Desktop
Note: The Source Code does not contain referenced external class library files.

Related Article

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.