打开互联网P2P套接字连接

6
这是一个经常讨论的话题,我知道。但我希望有一些创新的方法或我尚未遇到的方法来实现。基本上,我需要在两台客户机上运行的套接字之间建立点对点连接的方法。当然,主要问题是防火墙(应该可以做到)和需要进行端口转发。
现在,我熟悉UPNP等内容,我知道你有时候可以设置路由器进行端口转发,但那对我来说似乎是非常混乱的实现,更不用说不可靠了,因为用户可能会更换路由器,甚至使用没有UPNP或已禁用UPNP的路由器。
我虽然有些不情愿,但我很乐意添加一个中间服务器来促进连接,如果需要的话。但是除了简单地从一个流复制到另一个流(相当于将两个电话粘在一起,其中一个的扬声器面对另一个的麦克风,反之亦然),但正如这个比喻所暗示的那样,这样做似乎并不是最好的方法。也许有一种方法可以将两个独立连接的不同套接字连接起来?
我看到了很多问题,几乎都是关于我想要的内容,我认识到将其标记为某些问题的重复,但我主要想知道像TeamViewer或Skype这样的应用程序是如何实现的。(尽管我想Skype可能已经转向通过服务器进行所有通信,如果我没记错的话,但至少MSN Messenger曾经是P2P)。
所以问题是:我如何设置一个套接字,无论是否通过中间服务器,都可以从一个客户端机器连接到另一个客户端机器,而不必使用UPNP或类似不可靠的端口转发技术? 我在路上做了一些笔记:
- 至少 TeamViewer 为自己创建了几个防火墙例外。我没有任何问题这样做。但如果它采用了将两个电话放在一起的方法,为什么需要这些例外呢?出站请求通常会被默认批准。 - 我听说过 HTML5 和 WebSockets 允许浏览器之间进行聊天,但是这是如何工作的?我看过一些关于此的帖子,并介绍了 WebRTC,但类似的技术是否可以在浏览器之外使用?我认为可以,因为网络一般来说对这些行为更具限制性。
仅供参考,我对客户端和必要的服务器都有完全控制权,因此我可以采取任何必要的措施。但是,我非常希望不必在发起请求的客户端上执行操作,因为我希望看到Internet Explorer在那个位置上运行。基本上,我想编写一个P2P代理,因此我肯定可以通过编写自己的套接字来进行一些更高级的操作,并显示它们(它不必工作得很好,只需要足够工作),但如果IE直接连接,则会令人惊叹。
请告诉我,我知道这也比我们在这里看到的要广泛一些,这可能更适合程序员,但我尽力保持尽可能具体。

我也对此很感兴趣,因为我正在做类似的事情。你有任何安全方面的顾虑吗?是否需要任何类型的TLS?顺便说一下,我一直在研究ZeroMQ。 - Bill Sambrone
@BillSambrone 我宁愿先让它正常工作,然后再考虑那些东西。但是,我不认为我会费心去做这件事。我正在处理的是一个相当低频的问题,因此从维护的角度来看,添加安全性这样的额外复杂性似乎不值得。 - Matthew Haugen
1
我认为你的中间服务器方案是唯一的解决方法。这是我对TeamViewer和Skype等软件如何工作的假设。甚至像Hamachi这样的其他软件也是如此。我还认为你的电话类比可能是首选的方法(可能是我会采取的方式),但我没有足够的经验来确定这一点。 - E. Moffat
1
我预计这个问题会涉及到“孔”和“打孔”的词汇。 - mostruash
1个回答

3
Teamviewer、Skype和类似的P2P应用程序使用UDP打洞机制来进行IPv4 NAT穿越,这使得P2P应用程序成为可能。但是如果禁用了UDP或NAT路由器是对称的,则此类打洞机制将无法正常工作。如果网络不支持打洞,所有P2P机制都会回退到中间服务器代理方法。如果您正在为家庭用户构建应用程序,则可以有90%的成功率建立P2P连接。但在企业世界中,只有极少数允许P2P连接,因为大多数人出于安全原因而使用HTTP代理服务器代替NAT。还有一种P2P连接机制是使用IPv6套接字。使用ipv6,不需要NAT,机器可以直接使用全局ipv6地址进行访问。此机制至少在Windows Vista及以上PC上有效,因为它们默认使用像teredo、6to4之类的Ipv6过渡技术具有IPv6地址。您可以在Windows计算机上看到此ipv6地址,前缀为2001:这是使用该地址可以直接与PC建立连接,无需任何中间服务器的全局ipv6地址。即使ipv6有点不可靠,因为一些PC没有启用它。总之,您可以使用上述两种机制来构建应用程序以大多数情况下建立P2P连接,但有时需要回退到中间服务器。

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