P2P原理及UDP穿透簡單說明

P2P原理及UDP穿透簡單說明
博客分類: P2P
C
C++
C#
QQ


P2P原理及UDP穿透簡單說明

本文章出自cnntec.com的AZ貓著,如需要轉發,請註明來自cnntec.com

Peer-To-Peer縮寫P2P
中文稱之爲對等聯網。
用途於交流,比如QQ,MSN等等。
文件傳輸、分佈式數據計算等等。

這裏我們主要是是簡單講解一下UDP實現NAT的穿透(俗稱打洞)
當然TCP與之相似,可以以此類推。

NAT最開始出現在路由器上。詳細的大家可以在網上查下資料
NAT的全稱是Network Address Translator中文稱之爲網絡地址轉換
NAT分爲兩大類,NAT和NAPT(Network Address Port Translator)這個不用說了,端口地址轉換。

用於實例,簡單的說,實現P2P需要一箇中轉服務器。也就是需要一個第三方。(一會兒我們來說爲什麼需要一個第三方)

以簡單的通迅來講,首先我們來看一個示例圖。

A<——————>B A與B之間進行的通迅
A的IP地址爲222.182.100.1
B的IP地址爲222.182.100.2
如果這兩個用戶都是採用的全球唯一的IP地址,那麼他們通迅很簡單,也不需要實現P2P。
A<------------------>Nat<-------------------->B
如果其中一方爲內網用戶,及IP地址不爲全球唯一IP
就會出現通過路由器進行通迅。
那麼在經過路由器的時候,路由器會出現映射IP地址與端口的情況。
如:A爲內網用戶。B爲外網用戶。則B的IP地圖爲全球唯一IP地址。可以直接通迅。
A的IP地址爲:192.168.1.100 端口爲1025
經過路由器向B進行通迅,路由器將會產生一個一分鐘到幾小時不定的一個Session,這個Session映射了內網A的IP地址及其接收信息的端口。
那麼路由向B發送信息的時候,IP地址及端口就變成了222.182.100.1:3645(假設)
這個時候實際上A就是在進行路由NAT的穿透,
如果我們在B向A發送信息的時候採用192.168.1.100:1025這樣的IP和端口,是找不到A的,因爲這個IP不是全球唯一IP。
那麼B需要的是在收到A的信息的時候,獲取其IP地址和端口,那麼獲取到的就是222.182.100.1:3645這個路由器的映射Session地址。
B現在只需要向這個映射地址發送消息,路由器就會自動將消息發送到對應的A方去。否則路由器將當作無用包,將這個消息丟棄。
那如,我們現在就實現了局域網向某單個固定外網機器發送消息。
如果再來一臺C端,也是外網的IP。C通過222.182.100.1:3645向A發送消息,A是否能收到呢?答案是否定的,A不能收到。爲什麼?因爲路由在映射A的穿透時就記錄了B的地址,也就是除了B向這個映射點發送消息可以通向A,其它的地址是不行的。路由器此時會將其當作無用包消息給丟棄掉。
那怎麼辦呢?只有A再向C發送一個穿透,C纔可以向A發送消息。

以上我們只是說了一點基本的理論。接下來我們要實現什麼?不同內網通過internet網進行通迅。
再來,我們舉個圖例

A<----------->NatA<---------->NatB<---------->B
A的地址是:192.168.1.100端口4000
B的地址是:192.168.1.100端口4000
它們兩個都是內網的地址。及局域網內部地址。並不是全球唯一地址。
兩個路由:
NatA的地址是:222.182.100.1
NatB的地址是:222.182.100.2
這兩個路由是外網的地址,及全球唯一地址。

現在我們要實現A與B的通迅。
因爲A與B都不是外網地址。所以A不可能向192.168.1.100發送消息。這消息只會它自己收到,因爲這個IP是它自己的。同樣B也不可以。
那麼A向NatB發送消息,B能收到嗎?答案是否定的,不能收到。剛纔我們提到過。因爲路由沒有映射B的地址。A並不知道這個Session就連NatB也不知道這個Session因爲B沒有向A發送消息,並不產生這個Session。
就算B和A同時向雙方的路由發送消息,產生的Session,A和B也得不到。因爲在路由上就把這個消息當做爲無用包給丟棄掉了。

那麼這樣的情況我們要進行通迅怎麼辦呢?
對,就是剛纔我們提到的第三方。第三方是個什麼方呢?
第三方必須是一個擁有固定外網IP的服務方。及一個外網服務器。全唯一IP地址。

圖例:
假定我們這個第三方爲C
C IP:222.182.100.3端口4001
A<----------->NatA<--------------->C<-------------------->NatB<------------->B
↑______________________________↑

原理如下
A通過路由向C發送消息,C獲取A的在路由上的Session地址,映射的IP和端口
B同樣。
這時候C就有了A和B的地址。
C可以和A、B進行通迅,但是A和B還不行。
現在C需要通知A方B的映射IP和端口。也要通知B方A的映射IP和端口。
這樣A就有了B的映射地址,B也有了A的。但是現在還不能進行通迅。
因爲在路由上A和B都只有對C的穿透。並沒有相互之前的穿透。
那麼A要向B發送消息怎麼辦呢?需要C向B發送一個消息告訴B方A的地址讓B向這個地址發送一個消息,對A進行一個穿透。
這樣A就可以向B發送消息了。在A向B發送消息的同時,A也在向B進行穿透。
這樣就可以實現相互的通迅了。如果有多個端點,也就以此類推了。
宗上所述就是P2P的UDP實現原理了。
TCP也是一樣的。提示一點。Session在路由上是有時限的,一分鐘到幾小時不定。不同的路由不同的時間,爲了保持這個Session的存在,你需要在固定時間點進行通迅,保持這個穿透,否則就得重新穿透。

值得注意的一點。
路由上的映射有兩種情況
第一種情況是:Cone NAT
第二種情況是:Symmetric NAT
我們以上的實現是以Cone Nat爲基礎的。爲什麼呢?因爲Cone Nat在映射的時候端口是不變的。無論你內網有多少臺機器,向外網發送消息在路由上映射的端口都是不變的。
而Symmetric Nat則相反,一個映射一個端口。如果碰到這種情況只有祝你好運了,最好不要猜。(十有八九猜不到。所以不推薦猜)

分享到:

小學生讀西遊記
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章