15

我已经看过并阅读了很多类似的问题,以及相应的维基百科文章(NAT traversalSTUNTURNTCP 打孔),但是大量的信息并没有真正帮助我解决我非常简单的问题:

我正在编写一个 P2P 应用程序,我希望我的应用程序在 NAT 后面的两个用户能够相互连接。连接必须可靠(与 TCP 的可靠性相当),所以我不能只切换到 UDP。该解决方案无需重新配置即可在当今的通用系统上运行。如果有帮助,该解决方案可能涉及可连接的第 3 方,只要它不必代理整个数据(例如,获取对等方的外部 (WAN) IP 地址)。

据我所知,我唯一的选择是使用“可靠的 UDP”库 + UDP 打孔。是否有(C/C++)库为此?我在一个相关问题中找到了enet,但它只处理解决方案的前半部分。

还要别的吗?我看过的东西:

  1. Teredo 隧道- 需要操作系统和/或用户配置的支持
  2. UPnP端口转发 - UPnP 不存在/无处不在
  3. TCP 打孔似乎是实验性的,仅在某些情况下有效
  4. SCTP的支持程度甚至低于 IPv6。UDP 上的 SCTP 只是花哨的可靠 UDP(见上文)
  5. RUDP - 几乎没有主流支持
  6. 根据我对 STUN、STUNT、TURN 和 ICE 的理解,它们都不会帮助我。
4

2 回答 2

6

ICE收集要连接的候选 IP/端口目标列表。每个对等点收集这些,然后每个对等点按顺序对每个候选者运行连接检查,直到检查通过或检查失败。

当 Alice 尝试连接到 Bob 时,她以某种方式获得了可能的方式列表 - 由 Bob 确定 - 她可以连接到 Bob。ICE 称这些候选人。Bob 可能会说,例如:“我的本地套接字的 192.168.1.1:1024/udp,我的外部 NAT 绑定(通过 STUN 找到)是 196.25.1.1:4454/udp,您可以在 1.2 调用媒体中继(中间盒) .3.4:6675/udp”。Bob 将其放入一个 SDP 数据包(对这些不同候选者的描述),并以某种方式将其发送给 Alice。(在 SIP 中,ICE 的原始用例中,SDP 承载在 SIP INVITE/200/ACK 交换中,建立 SIP 会话。)

ICE 是可插拔的,您可以配置候选人的精确性质/数量。您可以尝试直接链接,然后向STUN服务器请求绑定(这会在您的 NAT 中打一个洞,并告诉您该洞的外部 IP/端口,您将其放入会话描述中),然后返回要求TURN服务器中继您的数据。

ICE 的一个缺点是你的同行交换SDP描述,你可能喜欢也可能不喜欢。另一个是 TCP 支持仍处于草案形式,这对您来说可能是也可能不是问题。[更新:ICE 现在正式成为RFC 6544。 ]

游戏经常使用 UDP,因为旧数据没用。(这就是 RTP 通常在 UDP 上运行的原因。)一些 P2P 应用程序经常使用中间盒或中间盒网络。

IRC 使用中间盒网络:IRC 服务器形成网络,客户端连接到附近的服务器。从一个客户端到另一个客户端的消息可能会通过服务器网络传播。

如果做不到这一切,你可以看看 BitTorrent 的架构,看看他们是如何处理 NAT 问题的。正如 CodeShadow 在下面的评论中指出的那样,BitTorrent 依赖于网络中可访问的对等点:在某种意义上,一些对等点形成了中间盒网络。如果这些中间盒可以充当中继器,那么您将拥有类似 IRC 的架构,但它是动态设置的。

于 2010-09-01T20:47:46.297 回答
3

我推荐libjingle,因为它被一些严重依赖 P2P 网络通信的主要视频游戏公司使用。(您听说过 Steam 吗?Vavle 也使用libjingle,请参阅页面中的“点对点网络”会话:https ://partner.steamgames.com/documentation/api )

但是,始终工作的解决方案将使用中继服务器。由于没有通过 NAT 的“标准”方式,因此如果必须始终在任何对等方之间建立连接,则应该将此中继服务器选项作为备用策略。

于 2011-02-23T19:27:01.990 回答