编程 P2P 应用程序
Posted
技术标签:
【中文标题】编程 P2P 应用程序【英文标题】:Programming P2P application 【发布时间】:2012-01-21 08:09:51 【问题描述】:我正在编写一个在端口 4900 上运行的自定义 p2p 程序。在某些情况下,当此人位于路由器后面时,无法从 Internet 访问此端口。
是否有一种自动方法可以从互联网启用对端口的访问。我不太确定其他 p2p 应用程序是如何工作的。
任何人都可以解释一下吗?
【问题讨论】:
Is there a UPnP Library for .NET (C# or VB.NET)? 的可能重复项 @David 我不同意重复,尽管 UPnP 确实是“答案”。 @jv42:很公平,这就是为什么关闭需要 5 票。至少,它将 OP 指向有用的相关信息。我认为 *** 礼仪更喜欢以这种方式链接重复项,而不是重新发布相同的答案。但我可以看到这两者的不同之处。无论哪种方式,只要帮助了 OP,任务就完成了:) @David:我明白了。作为用户,我确实更喜欢直接回答问题,即使它用非常简短的解释指出“重复”。 我已经发布了我的问题,与您的问题相关,但不完全是***.com/questions/54118006/***-with-webrtc-stun-ice 【参考方案1】:我会使用 WebRTC 技术作为此类应用程序的开源框架。
Official Website
事实上,它是一个开放源代码项目,支持开箱即用的点对点技术所需的一切:
ICE 和 STUN(NAT 遍历) DTLS 和 SRTP(安全) 用于流媒体质量的 AVPF。【讨论】:
【参考方案2】:您还有另一个选择是NAT Port Mapping Protocol (NAT-PMP) NAT-PMP 被 Skype 或 BitTorrent P2P 客户端等 VoIP 应用程序广泛使用。
【讨论】:
继任者是Port Control Protocol。【参考方案3】:简而言之,P2P 连接。假设我们在这里谈论的是 UDP。通过一些调整,以下步骤也可以应用于 TCP。
枚举所有本地 IP 地址(通常只有 1 个)。在给定的端口号**上为每个具有 IP 地址的适配器创建一个 UDP 套接字。
对于在第 1 步中创建的每个套接字,联系具有相同套接字的 STUN 或 TURN 服务器以发现您的外部 IP 地址并发现内部端口号映射到 NAT 外部的内容(并不总是相同的)端口值)。也就是说,你的本地地址 192.168.1.2:4900 对于外界来说可能是 128.11.12.13:8888。并且一些 NAT 在使用相同的本地端口到其他 IP 地址时并不总是使用相同的端口映射。 TURN 还会为您提供一个“中继地址”。如果路由器支持该协议,您还可以使用 UPNP 直接从路由器获取端口映射地址。
通过集合服务(SIP、XMPP、即时消息、Web 服务、电子邮件、带字符串的杯子),将您的地址候选列表发布到服务或向其他客户端发送通知,内容为“嘿,我想和你联系”。此消息包括在步骤 1 和 2 中收集的所有“候选地址”(ip 和端口对)。
远程客户端在收到连接邀请后,也会执行上述步骤 1 和 2。然后通过他收到邀请人候选人名单的同一渠道发回他的候选人名单。
打孔步骤。两个客户端都开始通过 UDP 向对方的地址候选者发送测试消息,并在他们的一端侦听相同的消息。每当收到消息时,请回复它来自的地址。最终,客户端会发现他们有一对地址,他们也可以可靠地发送数据报。通常,一个端点最终决定与哪个地址对(套接字)进行通信,并且协议有助于该端点将这个决定告诉另一个端点。
**- 通常最好不要依赖 P2P 客户端的知名端口。因为同一 NAT 或防火墙后面的两个客户端不可能同时使用您的软件。
这里是一些需要探索的技术的简要总结。
STUN - 是一个简单的服务器和协议,供 NAT/路由后面的客户端发现其外部 IP 和端口映射是什么。
TURN 是 STUN 的扩展,但支持中继用于防火墙和 NAT 阻止直接连接的 P2P 连接场景。
ICE 是使用 STUN 和 TURN 建立 P2P 连接的一组步骤。 ICE 是上述步骤 1-5 的正式协议。 ICE 上的两组优秀幻灯片是 here 和 here。
WebRTC 是 ICE 标准的变体,也是使用 STUN 和 TURN 进行 P2P 会话的参考库。
UPNP + Internet Gateway Device Protocol - 一些路由器支持主机自动获取端口映射。
libnice 是一个用于 Linux 的开源 C 库(可能适用于 Windows),它实现了 ICE。
libjingle 是 Google 的另一个 ICE 实现(C++)。适用于 Windows 和 Linux。
PJNATH 是PJSIP 编码库套件中的一个库。它是 ICE 堆栈(C 代码)的良好实现,并已移植到许多平台。 (Windows、Linux、Mac、ios、Symbian 以及即将推出的 android)。
最后,我有一个公然的插件供你使用my STUN server code base。
【讨论】:
感谢您的解释。 @selbie ,如果其中一个或两个对等方落后于 Double NAT,STUN/TURN/ICE 实施是否可以工作? @jagsgediya - 是的。很可能会通过 TURN 收敛。 @selbie 我仍然不清楚这些东西是如何工作的。假设 STUN 服务器返回128.11.12.13:8888
用于 Natted ip 和端口 192.168.1.2:4900
假设我想将我的端口 3000 暴露给外界。我是否将所有到达端口 4900 的请求转发到端口 3000
如果您尝试运行一个任何客户端都无法连接的专用服务器,那么这些东西都不适用。如您所述,您只需在路由器和防火墙上打开一个端口。如果您尝试在不手动配置 NAT 的情况下与另一台计算机动态建立临时短期连接,则适用上述 P2P 说明。【参考方案4】:
这可能比您正在寻找的要复杂一些,但 TCP 打孔是一种应该有效的技术。 http://en.wikipedia.org/wiki/TCP_hole_punching
另外,UPnP 非常适合支持它的路由器/防火墙。
【讨论】:
【参考方案5】:在某些情况下有解决方案,见 UPnP:https://en.wikipedia.org/wiki/Universal_Plug_and_Play#NAT_traversal
我的家用路由器允许这样做,基本上,NAT 可以通过来自计算机的适当请求自动配置。
我不会指望这会大大提高您的可用性,因为没有多少路由器支持并启用它。
编辑:@David 为 UPnP 的 .NET 库建议了这个 SO 问题:Is there a UPnP Library for .NET (C# or VB.NET)?
【讨论】:
以上是关于编程 P2P 应用程序的主要内容,如果未能解决你的问题,请参考以下文章