P2P应用中的直接TCP/IP连接

4

来自Joel关于Copilot的帖子:

直接连接!我们一直尽最大努力确保Fog Creek Copilot可以在任何网络环境下连接,无论有什么防火墙或NAT。为了实现这一点,双方都会向我们的服务器发出出站连接请求,服务器代表它们中继流量。嗯,在许多情况下,这并不是必要的。因此2.0版本做了一件相当聪明的事情:它通过我们的服务器建立起最初的连接,这样您就可以100%地可靠地连接。但是,一旦你连接上了,它就安静地在后台寻找建立P2P(peer-to-peer)连接的方法。如果没有,那没关系:你只需继续通过我们的服务器进行中继。如果您可以建立直接的点对点连接,它会将您的数据悄悄地转移到直接连接上。除了可能更快的通信之外,您不会注意到任何东西。

他们如何将服务器连接更改为P2P连接?

3个回答

10

这个很棘手,但也很有趣。我相信我可能有些细节理解错误,但概述如下:

这些程序已经通过Joel的服务器相互通信,因此它们可以相互交换信息并与Joel的服务器通信。此外,Joel有它们的外部IP地址,并且他们向Joel提供了关于他们的内部IP地址的信息。

他们决定尝试这种“破洞技术”。计算机A使用B的外部IP地址初始化与计算机B的TCP连接。连接不会成功,但它告诉A的路由器需要允许从B进入给定端口的传入数据包。

计算机B也做同样的事情,但是它的消息可以通过到达A,因为A的路由器打开了一个与B发送的匹配端口/IP组合相对应的端口。在这里发生了一些端口魔法 - 这是非平凡的,但可行的。

B的路由器记住了B在给定的端口和IP上与A建立了连接,因此A的数据包现在也能正确地流入B的路由器中。

所以实际上这很简单,但是实现细节很复杂,特别是关于如何为新的TCP连接分配端口,以及NAT路由器通常如何处理TCP请求以及如何映射到外部端口等方面。这些细节是有趣且困难的部分。

-Adam


那么当 A 获取 B 的 IP 时,它会打开一个新的套接字连接到 B 吗?还是使用连接到中央服务器时使用的相同套接字?我希望后者不是这种情况,因为那样他们还需要同步他们的 seq 和 ack 数字。 - ffff
1
@FaizHalde,细节比这篇文章所需的还要复杂。请考虑提出一个新问题来了解NAT打洞方法的工作原理。 - Adam Davis

1

有一种技术叫做“打洞”,它与“锥形”NAT(锥形是路由器的一个技术家族)非常配合。这并不是一种100%可靠的技术,但今天,在大约80%的路由器上,它在UDP上运行良好。

有一些库的实现可以实现打洞:STUNwikipedia


1

我认为简单的版本是,他们断开了服务器连接,并用P2P连接替换它。

大致如下:

  1. Machine1连接到copilot的服务器。
  2. Machine1连接到copilot的服务器。
  3. Machine1连接到copilot的服务器。
  4. 随后Machine2连接,他们开始屏幕共享。
  5. Machine2打开一个端口,供Machine1连接。
  6. Machine1尝试连接到现在打开的Machine2端口。

如果建立了此连接:

  1. 与copilot的服务器的连接将被切断。
  2. 数据将通过两台机器之间的直接(P2P)连接传输。

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