简而言之,P2P 连接。假设我们在这里讨论的是 UDP。经过一些调整,以下步骤也可以应用于 TCP。
枚举所有本地 IP 地址(通常只有 1 个)。为每个具有 IP 地址的适配器在给定端口号**上创建 UDP 套接字。
对于步骤 1 中创建的每个套接字,联系具有相同套接字的 STUN 或 TURN 服务器,以发现您的外部 IP 地址并发现内部端口号映射到 NAT 外部的内容(它并不总是相同的端口值)。也就是说,您的本地地址 192.168.1.2:4900 对于外界来说可能是 128.11.12.13:8888。当使用相同的本地端口到其他 IP 地址时,某些 NAT 并不总是使用相同的端口映射。 TURN 还将为您提供一个“中继地址”。如果路由器支持该协议,您还可以使用 UPNP 直接从路由器获取端口映射地址。
通过集合服务(SIP、XMPP、即时消息、Web 服务、电子邮件、带字符串的杯子),将您的地址候选列表发布到服务或向其他客户端发送通知,说:“嘿,我想与您联系”。此消息包括在步骤 1 和 2 中收集的所有“候选地址”(IP 和端口对)。
远程客户端在收到连接邀请后,也会执行上述步骤 1 和 2。然后通过他接收邀请者的候选人列表的同一渠道发回他的候选人列表。
打孔步骤。两个客户端开始通过 UDP 向对方的候选地址发送测试消息,并在各自的一端侦听相同的消息。每当收到消息时,请回复消息来源的地址。最终,客户端会发现他们有一对地址,他们也可以可靠地发送数据报。通常,一个端点最终决定与哪个地址对(套接字)进行通信,并且协议帮助该端点告知另一端点这一决定。
**- 通常最好不要依赖 P2P 客户端的众所周知的端口。因为同一 NAT 或防火墙后面的两个客户端不可能同时使用您的软件。
以下是一些需要探索的技术的快速总结。
STUN http://en.wikipedia.org/wiki/STUN- 是一个简单的服务器和协议,供 NAT/路由后面的客户端发现其外部 IP 和端口映射。
TURN http://en.wikipedia.org/wiki/TURN是 STUN 的扩展,但支持防火墙和 NAT 阻止直接连接的 P2P 连接场景的中继。
ICE http://en.wikipedia.org/wiki/Interactive_Connectivity_Establishment是使用 STUN 和 TURN 建立 P2P 连接的一组步骤。 ICE 是上述步骤 1-5 的正式协议。 ICE 上的两套优秀幻灯片是here http://www.jdrosen.net/uploads/1/5/0/0/15008848/ice-basic-tutorial.pptx and here http://www.jdrosen.net/uploads/1/5/0/0/15008848/ice-ietf-tutorial2.pptx.
WebRTC http://www.webrtc.org/是 ICE 标准的变体,也是使用 STUN 和 TURN 进行 P2P 会话的参考库。
UPNP + 互联网网关设备协议 http://en.wikipedia.org/wiki/Internet_Gateway_Device_Protocol- 有些路由器支持主机自动获取端口映射。
libnice http://nice.freedesktop.org/wiki/是一个用于 Linux(并且可能在 Windows 上工作)的开源 C 库,它实现了 ICE。
libjingle http://code.google.com/apis/talk/libjingle/index.html是 Google 的另一个 ICE 实现(C++ 语言)。适用于 Windows 和 Linux。
PJNATH http://trac.pjsip.org/repos/wiki/Using_Standalone_ICE是一个图书馆PJSIP http://www.pjsip.org/编码库套件。它是 ICE 堆栈(C 代码)的良好实现,并且已被移植到很多平台。 (Windows、Linux、Mac、iOS、Symbian 以及即将推出的 Android)。
最后,我有一个明目张胆的插头供你使用我的 STUN 服务器代码库 https://github.com/jselbie/stunserver.