views:

91

answers:

1

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.

A: 

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);
    }
}
dtb
So I have them open a port on their router and have it redirect to them just like port forwarding?
TheMan
http://www.codeproject.com/KB/IP/upnpnattraversal.aspxI saw this a while back, is this what I need to do? Thought it seemed overly complicated, but if setting up forwarding is what I have to do.
TheMan
I haven't tried it, but *Mono.Nat* seems pretty straightforward to use. I've added some example code.
dtb
Alright, I'll give it a shot, Thanks man. I'll mark this up if it works.
TheMan
Bad news that didn't work, its a little broken. But you got me started down the right path and I found a solution that works http://code.google.com/p/tcmportmapper/ works great. Thanks for your help man.
TheMan
You mean http://code.google.com/p/dotnetportmapper/ ? Thanks for testing this, now I know which library to use when I need a port mapper :-)
dtb
opps, I just saw that I linked the wrong one.
TheMan