自动端口转发 (UPnP ?) C++

Posted

技术标签:

【中文标题】自动端口转发 (UPnP ?) C++【英文标题】:Auto port forwarding (UPnP ?) C++ 【发布时间】:2012-11-03 01:34:07 【问题描述】:

免责声明我在这里仔细阅读了所有类似的主题并进行了谷歌搜索。没有人回答我的问题,所以我想在这个主题上积累信息。 附言我的英语可能不太好,对此感到抱歉。

我想做一个 p2p 应用程序(游戏)。显然,很多人会在一台机器上运行这个程序,该机器是具有一个互联网接入点(路由器)的本地网络的一部分,如果没有端口转发,应用程序根本无法工作。所以,我做了一项研究,发现我可以使用 UPnP 进行自动端口转发。编写微测试代码访问端口转发:

bool CPortController::Init() 


  HRESULT result = CoInitialize(NULL); // Must be NULL
  if (FAILED(result)) return false;

  result = CoCreateInstance(__uuidof(UPnPNAT), NULL, CLSCTX_ALL, __uuidof(IUPnPNAT), (void **)&Nat);
  if (FAILED(result) || !Nat) return false;

  result = Nat->get_StaticPortMappingCollection(&Collection); 
  if (FAILED(result) || !Collection) return false; // Here I'm getting S_OK as result, but Collection is always == 0

  return true;

搜索原因(见代码中的注释)我发现: 1.旧系统(不,我有更新的Win7) 2. 路由器可能没有 UPnP 功能或可能未启用 3. 防火墙可能阻塞了 UPnP 需要的 TCP 端口 2869 或 UDP 端口 1900

遗憾的是,我无法访问路由器来检查最后 2 个,但这并不重要,因为 Skype 和 uTorrent(均为 p2p)运行良好。我需要找到一种方法来使用我的应用程序自动执行相同的技巧并转发端口,而不要求用户执行任何操作。

关于 UPnP 库: 我发现很少有 UPnP 库(PlatinumUPnP、miniUPnP),但它们似乎有很多代码用于寻找智能设备并将它们放在一起......嗯......我不确定我是否需要这个来完成我的任务和我找不到用于自动端口转发的一段代码(没有使用上面列出的那些 WinUPnPAPI)。

我现在有点迷路了。谁能告诉我继续研究的方向?也许除了UPnP之外还有别的东西吗?也许有一个库(我错过了)可以使用?请传播一些光。提前谢谢你。

【问题讨论】:

Skype 通过使用一种称为NAT hole punching 的技巧避免了对 UPnP 的需求,该技巧需要公共服务器的合作。这意味着初始连接设置阶段不是 P2P,但后续通信是。 @Rook,感谢您让我了解 HolePunching。我读过几篇文章,看起来正是我所需要的。可悲的是,不能将您的评论标记为“已接受的答案”,因为它是作为评论发布的,但这完全值得!谢谢:) 好吧,我不打算让它成为答案,因为它根本不谈论 uPnP。帕维尔的回答在这方面更有用! 【参考方案1】:

从UPnP Developer Tools 运行DeviceSpy 并在您的网络中搜索InternetGatewayDevice。如果没有,您的路由器不支持 UPnP 或已禁用。如果有,请检查WANIPConnection 服务。请注意,从 InternetGatewayDevice v2(自 2010 年起)起,您不能在 UPnP 上设置静态端口映射(租用时间 0)。

正如@Rook 所指出的,还有其他方法可以建立 P2P 连接,因此 其他一些随机 P2P 软件 工作的事实并不一定意味着该软件知道如何配置您的端口映射。特别是 Skype 并不是真正的 P2P,it depends on huge number of dedicated supernodes。

【讨论】:

非常感谢。 (对不起,11声望不能给你投票,但你的评论很中肯,谢谢)

以上是关于自动端口转发 (UPnP ?) C++的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 中通过 UPnP 转发端口

端口转发 (NAT UPNP) 错误

26-Openwrt 端口转发 dmz upnp

如何以编程方式通过upnp实现双NAT端口转发

如何在java中自动端口转发?

简单的多人游戏网络,无需专用服务器或需要玩家手动转发端口(无 UPnP)