【问题标题】:How to create a P2P connection when both clients are behind NAT当两个客户端都在 NAT 之后时如何创建 P2P 连接
【发布时间】:2015-07-09 20:16:42
【问题描述】:

是否可以在两个位于不同 NAT 后面的客户端之间建立 直接 连接? 当然,我意识到在某种程度上,具有公共 IP 的服务器将是必不可少的,但我不希望它成为代理。看看下面的场景:

  • 我不想与配置网络设备有任何关系。我只想用代码来做。
  • 我不希望服务器参与文件传输过程(出于性能原因)
  • 我们有:客户端 A、客户端 B 和服务器 S,看起来有点像这样:

A--[Router1]--S--[Router2]--B

  • A连接S并授权
  • B连接S并授权
  • A 想向 B 发送文件
  • A 向 S 请求与 B 的连接
  • S [这里有魔法吗] 现在 A 与 B 建立了连接
  • A开始发送文件
  • S 宕机(或至少文件传输绕过是)
  • A 和 B 之间仍然存在联系
  • A 继续向 B 发送文件

我的问题:

  1. 这可能吗?
  2. 如何做到这一点?
  3. 遇到过可以做到这一点的示例项目吗?

我找到了WCF / WPF Chat Application,但原来是代理。

我还发现了一些建议使用 UPnP 和 NAT Traversal 的帖子,但没有人直接回答我的第一个问题,所以我没有深入研究。

【问题讨论】:

    标签: c# .net tcp


    【解决方案1】:

    您正在寻找“神奇部分”的术语称为NAT Hole Punching。不幸的是,这个主题有点过于宽泛,无法在此处完全解释如何完成它,但现在知道正确的术语应该至少可以让您开始寻找正确的教程。

    这是来自UDP Hole Punching 页面的算法摘要。

    假设 A 和 B 是两台主机,各自在自己的专用网络中; N1 和 N2 是两个 NAT 设备,其 IP 地址为全球可达 P1 和 P2分别; S是全球知名的公共服务器 可访问的 IP 地址。

    1. A 和 B 各自开始与 S 的 UDP 会话; NAT 设备 N1 和 N2 创建 UDP 转换状态并分配临时外部 端口号 X 和 Y
    2. S 检查 UDP 数据包以获取 N1 和 N2 使用的源端口(外部 NAT 端口 X 和 Y)
    3. S 将 P1:X 传递给 B,将 P2:Y 传递给 A
    4. A 向 P2:Y 发送一个数据包,B 使用与 S 对话相同的源端口向 P1:X 发送一个数据包,从而“打孔” NAT 到另一台主机
    5. 如果任一主机收到数据包,则打孔成功,两台主机可以通信。

    如果两个主机都有Restricted cone NATsSymmetric NATs,则外部 NAT 端口将与 S 使用的端口不同。在某些情况下 路由器,外部端口按顺序选择,使其成为可能 通过猜测附近的端口来建立对话。

    它是否会工作在很大程度上取决于两个端点的 NAT 路由器的行为方式,很可能您的很大一部分使用会配对,并且两者都有不“打孔友好”的路由器。

    在您的情况下,我会让我的软件按顺序尝试这些步骤。

    1. 检查我们是否可以连接(用户进行了手动端口转发)
    2. 使用 UPnP 并打开一个端口
    3. 使用某种形式的打孔,使用公共服务器作为两者之间的过渡
    4. 使用另一个打开了端口的对等点作为数据代理(Supernode)。
    5. 使用我托管的服务器作为代理转发数据。

    【讨论】:

      猜你喜欢
      • 2015-11-04
      • 2015-10-10
      • 1970-01-01
      • 2018-07-08
      • 2019-05-29
      • 1970-01-01
      • 2012-12-31
      • 2011-09-12
      • 1970-01-01
      相关资源
      最近更新 更多