2016-11-02 85 views
2

我最近一直在尝试为我的游戏设置端口映射。这是为了让其中一名球员成为主人。为此,我需要玩家打开端口7777.Unity .Net 2.0 UPNP端口映射

如果已经有一个匹配,它只会加入它。如果它没有找到空的匹配,它只会做一个。如果它没有成功,它会一直等到有人加入并加入。

因此,我需要能够使用类似UPnP的东西来端口映射我的端口。我还需要能够发现错误,看看是否继续创建比赛,或者只是等待和加入比赛。

我目前在使用.NET 2.0的Unity游戏引擎工作。这使得我非常有限,因为Open.NAT不兼容。我尝试过Mono.NAT,但我无法正常工作。

有没有人有任何建议我应该如何处理?什么图书馆使用,甚至可以提供我的代码片段让我开始。

谢谢,TwoTen。

EDIT1:当前Mono.NAT代码如下所示:

private void DeviceFound(object sender, DeviceEventArgs args) 
{ 
    Debug.Log("1"); 
    INatDevice device = args.Device; 
    Debug.Log("2"); 
    Mapping map = new Mapping(Protocol.Tcp, 6699, 6699); 
    Debug.Log("3"); 
    device.CreatePortMap(map); 
    Debug.Log("4"); 
    int test = device.GetAllMappings().Length; 
    Debug.Log(test); 
    foreach (Mapping portMap in device.GetAllMappings()) 
    { 
     Debug.Log("5"); 
     Debug.Log(portMap.ToString()); 
    } 
} 
private void DeviceLost(object sender, DeviceEventArgs args) 
{ 
    INatDevice device = args.Device; 
    Mapping map = new Mapping(Protocol.Tcp, 6699, 6699); 
    device.DeletePortMap(map); 
} 

我被称为最后的调试语句是4号。我的端口不会被打开,没有EXCETION要么抛出。 我在做什么错?

而且,在我启动功能我称之为:

NatUtility.DeviceFound += DeviceFound; 
NatUtility.DeviceLost += DeviceLost; 
NatUtility.StartDiscovery(); 
+0

“我试过Mono.NAT,但我无法得到它的工作”请张贴代码。这对我有用。我需要看看你在做什么。另外,你怎么知道它不工作? – Programmer

+0

我更新了帖子以包含我的代码。 – TwoTen

+0

用'Debug.Log(“4 ++”+ test)重新调试'Debug.Log(test);'然后用Log重新更新问题。另外,你在哪里放置Mono.NAT DLL? – Programmer

回答

1

我已经找到了如何成功地找到答案。我放弃了Mono.NAT,而是使用了Open.NAT,该Open.NAT已移植到与Unity兼容的.NET 3.5。

最终的代码,我结束了使用看起来像这样:

private static Task Test() 
{ 
    var nat = new NatDiscoverer(); 
    var cts = new CancellationTokenSource(); 
    cts.CancelAfter(5000); 

    NatDevice device = null; 
    var sb = new StringBuilder(); 
    IPAddress ip = null; 

    return nat.DiscoverDeviceAsync(PortMapper.Upnp, cts) 
     .ContinueWith(task => 
     { 
      device = task.Result; 
      return device.GetExternalIPAsync(); 

     }) 
     .Unwrap() 
     .ContinueWith(task => 
     { 
      ip = task.Result; 
      sb.AppendFormat("\nYour IP: {0}", ip); 
      return device.CreatePortMapAsync(new Mapping(Protocol.Tcp, 7777, 7777, 0, "myGame Server (TCP)")); 
     }) 
     .Unwrap() 
     .ContinueWith(task => 
     { 
      return device.CreatePortMapAsync(
       new Mapping(Protocol.Udp, 7777, 7777, 0, "myGame Server (UDP)")); 
     }) 
     .Unwrap() 
     .ContinueWith(task => 
     { 
      sb.AppendFormat("\nAdded mapping: {0}:1700 -> 127.0.0.1:1600\n", ip); 
      sb.AppendFormat("\n+------+-------------------------------+--------------------------------+------------------------------------+-------------------------+"); 
      sb.AppendFormat("\n| PORT | PUBLIC (Reacheable)   | PRIVATE (Your computer)  | Description      |       |"); 
      sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+"); 
      sb.AppendFormat("\n|  | IP Address   | Port | IP Address   | Port |         | Expires     |"); 
      sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+"); 
      return device.GetAllMappingsAsync(); 
     }) 
     .Unwrap() 
     .ContinueWith(task => 
     { 
      foreach (var mapping in task.Result) 
      { 
       sb.AppendFormat("\n| {5} | {0,-20} | {1,6} | {2,-21} | {3,6} | {4,-35}|{6,25}|", 
        ip, mapping.PublicPort, mapping.PrivateIP, mapping.PrivatePort, mapping.Description, 
        mapping.Protocol == Protocol.Tcp ? "TCP" : "UDP", mapping.Expiration.ToLocalTime()); 
      } 
      sb.AppendFormat("\n+------+----------------------+--------+-----------------------+--------+------------------------------------+-------------------------+"); 
      sb.AppendFormat("\n[Removing TCP mapping] {0}:1700 -> 127.0.0.1:1600", ip); 
      return device.DeletePortMapAsync(new Mapping(Protocol.Tcp, 1600, 1700)); 
     }) 
     .Unwrap() 
     .ContinueWith(task => 
     { 
      sb.AppendFormat("\n[Done]"); 
      Debug.Log(sb.ToString()); 
     }); 
} 

我所要做的就是要做到这一点,我启动功能:

Test().Wait(); 

路由器注册端口,并打开它。然而。网站canyouseeme.org未能看到该港口因任何原因而开放。要验证它是否已注册,我进入我的路由器设置并查找UPnP。当时有一份包括我的应用程序的列表。我还没有做真实世界的测试,但是我会在完成这些测试后更新这个帖子。

的Open.NAT版本兼容团结在这里找到:

编辑:我现在已经完成现实世界中的测试。一切工作正常,用户可以连接,不用中继和或统一的配对服务器