2011-12-15 201 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質量的流媒體。