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

15

免责声明我仔细阅读了这里的所有类似主题并进行了谷歌搜索。其中没有一个回答了我的问题,因此我想在这个主题中积累信息。 附注:我的英语可能不太好,对此表示抱歉。

我想制作一个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
遗憾的是,我无法访问路由器以检查最后两个原因,但这并不重要,因为Skype和uTorrent(均为P2P)都可以正常工作。 我需要找到一种方法,在不要求用户做任何事情的情况下使用我的应用程序自动进行端口转发。
关于UPnP库: 我找到了几个UPnP库(PlatinumUPnP,miniUPnP),但它们似乎有很多面向查找智能设备并将它们组合在一起的代码……嗯……我不确定我需要这个来完成我的任务,并且我找不到一段代码(不使用我上面列出的那些WinUPnPAPI)来进行自动端口转发。
我有点迷失了。 有人可以向我展示继续研究的方向吗? 也许还有别的方法可以实现自动端口转发? 可能有一个我错过的库可以使用吗? 请给予指引,谢谢您提前。

3
Skype使用一种称为“NAT穿透”的技巧来避免使用UPnP,这需要一个公共服务器的协作。这意味着初始连接设置阶段不是点对点(P2P),但随后的通信则是点对点的。 - Rook
@Rook,感谢您让我了解HolePunching。我已经阅读了几篇文章,看起来正是我所需要的。不幸的是,由于它是作为评论发布的,我无法将您的评论标记为“接受的答案”,但这绝对是值得的!谢谢 :) - JacksonRR
3
好的,我会尽力进行翻译:我本来不打算回答这个问题,因为它与uPnP无关。在这方面,Pavel的回答更加有用! - Rook
1个回答

18
UPnP开发工具运行DeviceSpy并搜索您的网络中是否有InternetGatewayDevice。如果没有,则说明您的路由器不支持UPnP或已禁用。如果有一个,则检查WANIPConnection服务。请注意,自从InternetGatewayDevice v2(自2010年以来),您不能通过UPnP设置静态端口映射(租约时间为0)。
正如@Rook所指出的,还有其他建立P2P连接的方法,因此某些其他随机的P2P软件能够工作并不一定意味着该软件知道如何配置您的端口映射。特别是Skype并非真正的P2P,它依赖于大量专用超级节点。

3
非常感谢。抱歉,11个声望不足以让我给你点赞,但是你的评论非常有帮助,谢谢。 - JacksonRR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接