2012-10-02 101 views
3

我試圖建立一個P2P即時消息系統,雖然我還沒有遇到這個問題,但我希望如果客戶端在本地局域網的NAT後面,我會遇到一些問題(閱讀:每個人。)通過NAT的P2P即時消息

讓我解釋一下算法,你會明白我的意思。有三個組件:一個服務器和兩個客戶端 - 客戶端Alice希望與客戶端Bob發起聊天。服務器只跟蹤誰在線,但實際的對話不通過服務器(爲了客戶端的隱私)

因此,Alice和Bob都登錄到服務器 - 連接到服務器的靜態偵聽從一個短暫的港口。他們告訴服務器他們正在偵聽傳入聊天請求的靜態端口。 Alice詢問服務器如何聯繫Bob。服務器響應ipaddress和偵聽端口等。 Alice將該請求發送給該IP地址和端口上的Bob以建立連接。希望這是有道理的。

如果Bob在NAT後面,那麼他確定他可以與服務器通話,因爲他是開始通信的人。但是愛麗絲的要求不會讓他接近他,因爲尚未針對他在愛麗絲的IP地址上收聽聊天請求的端口設置NAT關係。

有人知道做這種工作的某種黑魔法?這會不會成爲問題?發展還沒有那麼久,我還沒有真正遇到這個問題。

爲了說明這一點,我不想讓最終用戶爲其監聽端口配置端口轉發。

對於前面提到的黑魔法,客戶端和服務器都在Java中,但我只是一般的算法後(如果它甚至有可能)

+0

只要看看聊天系統,如jabber甚至Skype。您必須配置端口轉發,使用代理服務器或通常打開的後備端口,如80 ... – Fildor

回答

0

沒有黑魔法。如果兩個客戶端都在NAT後面,則消息必須通過第三方(服務器)。 如果只是關於文本消息(如果隱私是個問題,你可以考慮進行某種加密),我會考慮在所有通信中使用這種體系結構。服務器(或多個服務器)將被加載得更多,但你會變得更簡單(並且在某些情況下更可靠)體系結構。例如,如果Alice向Bob發送消息,並且Bob有一些網絡問題,則服務器可以將消息排隊並保留一段時間,並在稍後交付(即使Alice離線)。另一件事是會議(組)聊天。僅使用P2P進行處理更具挑戰性(但可能非常有趣)。但是如果所有的客戶都在NAT後面,你會遇到同樣的問題。 我也強烈建議爲所有傳輸和接收的消息(來自客戶端和服務器)實現應用程序級別的確認機制。協議如TCP/IP不夠可靠。

1

檢查ICE

大多數P2P框架,如Java中的JXTA,使用中繼服務器的原則。

說一個想連接到B和B在防火牆後面。

- both A and B establish ** outbound ** synchronous (or full duplex/websockets) connections to Relay Server R 
- A signals to R that it wants to transmit data to B 
- R 'binds' the inbound connection from A to the outbound connection to B (the synchronous HTTP response to B for instance) 
- A sends data to R which is relayed to B 

這裏的關鍵是,所有的連接建立出境(一種通常使用友好防火牆,如HTTP上衆所周知的端口協議)

,事情就顯得比較複雜一些,當你有分佈式繼電器;您需要通過依賴分佈式散列圖(DHT)維護信息的中繼來維護到各個對等點的路由。