Reputation:
How do I connect 2 different subnet’ed computers? For example sake let’s say the following:
192.168.1.92 connected to externally visible 222.251.155.20. 192.168.1.102 connected to externally visible 223.251.156.23.
Now there is middle man server that both machines are connected to so they can negotiate each other’s internal and external IP’s and have one open up a listening port. The only way I currently know how to do this is port forwarding.
I’m fairly proficient with C# sockets, just don’t how to connect two computers that are on two different subnets.
I have a server that the clients connect to that has a domain name, usally the clients will be behind home routers and I want them to be able to share information directly with each other.
Upvotes: 1
Views: 1601
Reputation: 217263
What you're looking for is NAT traversal. Solutions without a relaying server and without port forwarding usually use some form of UDP hole punching. A standardized mechanism is STUN (i.e. Interactive Connectivity Establishment).
Note: implementing UDP hole punching and reliable file transfer over UDP is not trivial. The best option is probably to automatically set up port forwarding with UPnP or NAT-PMP. There are libraries for both, e.g., Mono.Nat (sources):
class NatTest
{
public Start ()
{
// Hook into the events so you know when a router
// has been detected or has gone offline
NatUtility.DeviceFound += DeviceFound;
NatUtility.DeviceLost += DeviceLost;
// Start searching for upnp enabled routers
NatUtility.StartDiscovery ();
}
void DeviceFound(object sender, DeviceEventArgs args)
{
// This is the upnp enabled router
INatDevice device = args.Device;
// Create a mapping to forward external port 3000 to local port 1500
device.CreatePortMap(new Mapping(Protocol.Tcp, 1500, 3000));
// Retrieve the details for the port map for external port 3000
Mapping m = device.GetSpecificMapping(Protocol.Tcp, 3000);
// Get all the port mappings on the device and delete them
foreach (Mapping mp in device.GetAllMappings())
device.DeletePortMap(mp);
// Get the external IP address
IPAddress externalIP = device.GetExternalIP();
}
private void DeviceLost (object sender, DeviceEventArgs args)
{
INatDevice device = args.Device;
Console.WriteLine ("Device Lost");
Console.WriteLine ("Type: {0}", device.GetType().Name);
}
}
Upvotes: 1