2011-12-15 225 views
28

我正在编写一个运行在端口4900上的自定义p2p程序。在某些情况下,当此人在路由器后面时,此端口无法从Internet访问。编程P2P应用程序

是否有一种自动方式可以从互联网访问端口?我不太确定其他p2p应用程序的工作方式。

任何人都可以抛开一些光线吗?

+0

可能重复[是否有.NET(C#或VB.NET)的UPnP库?](http://stackoverflow.com/questions/333079/is-there-a-upnp-library-for -net-c-or-vb-net) – David 2011-12-15 16:29:29

+2

@David我不同意重复,虽然UPnP确实是'''的答案。 – jv42 2011-12-15 16:33:03

回答

89

P2P连接简而言之。假设我们在这里谈论UDP。以下步骤也可以应用于TCP并进行一些调整。

  1. 枚举所有本地IP地址(通常只有1个)。在给定端口号**上为每个具有IP地址的适配器创建一个UDP套接字。

  2. 对于在步骤1中创建的每个套接字,请联系具有相同套接字的STUN或TURN服务器以发现您的外部IP地址,并发现内部端口号映射到NAT之外(它并不总是相同的端口值)。也就是说,你的本地地址192.168.1.2:4900对外界可能是128.11.12.13:8888。而一些NAT在使用相同的本地端口到其他IP地址时并不总是使用相同的端口映射。 TURN还将为您提供“中继地址”。如果它支持该协议,您也可以使用UPNP直接从您的路由器获取端口映射地址。

  3. 通过一个聚会服务(SIP,XMPP,即时消息,Web服务,电子邮件,用绳子杯),发布您的地址候选者列表的服务或发送给其他客户端,上面写着:“好端端的一个通知,我想与你联系“。该消息包括在步骤1和步骤2中收集的所有“地址候选”(ip和端口对)。

  4. 远程客户端在收到邀请连接时也执行上述步骤1和2。然后通过他收到邀请者候选人名单的同一频道发送候选人名单。

  5. 打孔步骤。两个客户端都开始通过UDP向另一端的候选地址发送测试消息,并在其末尾收听相同的消息。每当收到消息时,回复它的来源地址。最终,客户端会发现他们有一对地址,他们也可以可靠地发送数据报。通常情况下,一个端点会对哪个地址对(套接字)进行通信做出最终决定,并且该协议有助于此端点告知其他端点此决定。

** - 通常最好不要依赖一个众所周知的P2P客户端。因为同一个NAT或防火墙后面的两个客户端不可能同时使用您的软件。

下面是一些要探索的技术的快速总结。

STUN - 一个简单的服务器和协议,用于客户端在NAT /路由后面发现他们的外部IP和端口映射。

TURN是对STUN的扩展,但支持中继用于防火墙和NAT阻止直接连接的P2P连接方案。

ICE是一组使用STUN和TURN建立P2P连接的步骤。 ICE是上述步骤1-5的正式协议。 ICE上的两套优秀幻灯片是herehere

WebRTC是ICE标准的一种变体,也是一个用于与STUN和TURN进行P2P会话的参考库。

UPNP + Internet Gateway Device Protocol - 某些路由器支持此功能,以便主机自动获取端口映射。

libnice是一个用于实现ICE的Linux的开源C库(可能适用于Windows)。

libjingle是Google的另一个ICE实现(使用C++)。对于Windows和Linux。

PJNATHPJSIP套编码库中的库。这是一个ICE栈(C代码)的良好实现,并已被移植到很多平台。 (Windows,Linux,Mac,iOS,Symbian和即将推出的Android)。

最后,我有一个公然的插头,供您使用my STUN server code base

2

我会使用WebRTC技术作为这种应用程序的开源框架。

Official Website

其实,这是它支持所有必要的对等网络技术的开箱即用的一个开源项目:

  • ICE和STUN(NAT穿越)
  • DTLS和SRTP(安全)
  • AVPF质量的流媒体。