How to register a global hotkey for your application in C#

How to register a global hotkey for your application in C#

Register a hotkey for your application that can be triggered even if your form is minimized and does not have focus. More »

How to download a file in C# (progressbar and download speed)

How to download a file in C# (progressbar and download speed)

Learn how to download files in C# while displaying the percentage and the download speed. More »

UDP hole punching implementation in C#

UDP hole punching implementation in C#

Learn how to implement UDP hole punching so you can make your clients life a lot easier by not forcing them to open ports on their end. More »

 

UDP hole punching implementation in C#

UDP hole punching is a method that is used to establish connectivity between two hosts that are behind a NAT (router) without the need of having the clients port forward specific ports.

When the client sends a UDP packet to the server the router creates a temporary rule mapping, the server then uses the incoming IP address and port it receives the message from to send a message to the client, which refreshes (in most cases) the lifetime of the temporary mapping on the client’s router and allows the server to communicate constantly with the client without the need for the user to do anything from their side.

This method is also used to send messages between two users that are behind different NAT’s. The difference in the implementation is that the clients first contact with the server, which should have a port open in order to be able to receive the information from the clients. After the server receives the information from the clients it sends each client the IP and port of the other client, allowing both of them to communicate with each other.

I’ve created a small example on how the implementation of a UDP hole punching looks in C#, this should give you the general idea of how it works and let you expand it as you like. The example simply receives a message from the client then sends a response. If you want the server to handle more than one message then you will need to add some loops.


First the server side, which will receive the information from the client then respond.
Server:

Then a method will send a message of our choice to our server and return the response.
Client:

Client usage:

Share on FacebookTweet about this on TwitterShare on Google+Share on StumbleUponShare on LinkedInShare on RedditPin on PinterestShare on TumblrDigg thisPrint this pageEmail this to someone

12 Responses to UDP hole punching implementation in C#

  1. souvik sett says:

    Hello, the tutorial is very very basic. Yet thanks for the tutorial. But why the author is silent in the question of P2P message? Many readers want to know this.

  2. Marcello Pietrobon says:

    The following article is one of the most clarifying I’ve found on the issues expressed by some responses written here: http://bford.info/pub/net/p2pnat/

  3. jake says:

    hello, i have small problem, only the server can send 1 message to the client after the client sends 1 message to the server. is it possible to have the server send messages to the client the same way the client can send them to the server? i had tried putting

    which should have sent 5 messages back to the client but it only send one?

    • CooLMinE says:

      You will need to create a loop for the Receive method otherwise it will block until a message is received then stop listening.

  4. Rory says:

    Yah I am desperate for an example of how to then connect the 2 clients. I understand the process but Im just not sure how the server is supposed to proceed and open that door.

    • CooLMinE says:

      The server does not open the port.

      The server is simply responsible to pass the information of host A (public IP and port) to host B and the information of host B to host A.

      After that takes place then host A and host B simply exchange information between them without going through the server.

  5. Odin says:

    How is this done using TCP?

    Thanks in advance :)

    • Jake says:

      Hello, i have a question to ask about this scenario, i know that the server is responsible for passing information of client A and client B their ip and port. the issue i am having, isn’t client A and client B open ports only listening for messages from the server. or is this different between TCP and UDP. i had made a test project and sent it to a friend, they can communicate to the server and server can communicate back with Nat Punch, however all traffic is sent from clients to server then back out to all other clients. this is fine since clients then do not have other clients IP and port, safety for Doss attacks. but if i wanted to allow the users to communicate to each other without sending the data through the server and relaying back to the clients do i need to open another port or can they use the same port that was opened when they connected to the server. (i believe its known as the Punch part) please correct me if im wrong i am doing this as a learning exercise and an intro to networking with c# sockets. and would love to get more involved with Nat punch through implementation without having the users manually port forward.

  6. AXER says:

    Hi, thanks for this guide, it works well for me. The only problem I have is that once you have these two endpoints, how do you get them to connect to each other?

    I’ve been stuck with this for a while now. For some reason sending to these endpoints, the clients just can’t connect. I will research more on NATs as my understanding is limited, just hope you could guide me in the right direction.

    Thanks

    • André V says:

      I’m stuck at this point as well… After I get the IPs and Ports of both behind-NAT-clients, how do you connect each other? I tried to use the same method used to connect with the server, but didn’t work… even if I Close() the connection first. Also, how do I maintain the “temporary port” open and guarantee that is the one the socket will use to connect with the other client?

  7. Monty Serafeim says:

    I was looking for an example on how to implemenent this, thanks

  8. Zach says:

    Great explanation, thank you for posting this

Leave a Reply

Your email address will not be published. Required fields are marked *