问题
Can anyone give an example of a UDP Hole Punching ?
Actually, I want to write a chat program with which people can chat when they know each other's IP. But both the machines will be behind a firewalled router. So, I need to punch a hole in order to communicate.
I would like a function such that on calling the function, a hole would have been punched and future communications would move on easily - if that's not too much to ask for :)
回答1:
Short Answer: it can't be done reliably.
Long Answer:
"Hole Punching" refers to triggering automatic NAT rules of a router in order to allow inbound traffic. When you send a UDP packet out, the router (usually) creates a temporary rule mapping your source address and port to the destination address and port, and vice versa. UDP packets returning from the destination address and port (and no other) are passed through to the original source address and port (and no other). This rule will timeout after some minutes of inactivity.
Getting this to work when both end-points are behind NATs or firewalls would require that both end-points send packets to each-other at about the same time. This means that both sides need to know each-other's public IP addresses and port numbers and need to communicate this to each-other by some other means.
There is no way for a program to directly determine its own public IP address if it is behind an NAT (it will only see its private address, such as 192.168.x.x
). But since you are assuming that the humans involved know each-other's IP addresses, those humans can just type in the other's address.
But the real catch is that there is also no way for a program to directly determine what port number the router is using on the public side. Your program may be bound to 12345 on the local machine, but the router can map that to almost any port on the public side. (Imagine two computers on your local network both sending out from port 12345, obviously the router will have to map one of them to a different number.) So even though you and the humans may know what local port number you are bound to, there's no way to know what port number the router will show to the world.
回答2:
Lidgren's networking library has this functionality built-in. After adding the library to your application, you would instantiate a NetServer, have two NetClients connect, and call NetServer.Introduce().
Link to Lidgren: https://github.com/lidgren/lidgren-network-gen3
来源:https://stackoverflow.com/questions/8892142/udp-hole-punching-algorithm