解決網絡通訊中外網和內網之間的通訊問題(NAT轉換)

本文原址 http://www.cnblogs.com/lidabo/p/3828846.htmlhtml

在網絡編碼中會發現程序在局域網中是能夠適用的,可是在外網與內網之間和內網與內網之間就不可行。
問題就在於NAT。首先介紹下NAT。 
NAT的做用NAT(Network Address Translator),網絡地址轉換。顧名思義,它是一種把內部私有網絡IP地址翻譯成公有網絡IP地址的技術,如圖5-1所示。NAT是在IP地址日益缺少的狀況下產生的,它的主要目的是使地址可以重用[9]。 
解決外網與內網或內網之間的通訊,NAT穿透 - sanerye - DreamEyesSKY 
圖5-1 NAT模型 
IP地址分爲五類:A類,B類,C類,D類,E類(這裏不考慮保留的IP地址)。A、B、C類可被計算機做爲IP地址,D類爲組播地址,E類爲特殊用途的地址。A、B、C類中,又可分爲公有地址和私有地址,私有地址用於內網,不一樣的內網,私有地址可重用,從而節省了公網地址,它不可在公網中被路由,因此內網的主機要訪問公網的服務器,便要通過NAT。公有地址是全球惟一的,能在公網上被路由。 
解決外網與內網或內網之間的通訊,NAT穿透 - sanerye - DreamEyesSKY 
內網主機用私有地址在內網能與其它的內網主機無誤地通訊,但它不能直接用私有地址訪問外網的主機,由於私有地址不能被路由。它要與外網通訊,必須通過NAT設備(如網關,路由器),如圖5-2所示。主機A與服務器S通訊,它須先經過網關,此時網關改變它的數據包地址及端口,把私有地址(10.0.0.2)改成公有地址(155.99.25.11),使數據包能在公網上被路由,送至服務器端。服務器端返回的數據包到達網關後,網關把公網地址改成相應的私有地址,而後轉發到主機A。經過這種方法,一個內網只需一個公有IP地址,就把整個內網的計算機接入Internet,從而解決IP地址缺少的問題。 
NAT功能一般被集成到路由器、防火牆、ISDN路由器或者單獨的NAT設備中。也可經過軟件實現這一功能,Windows 98 SE、Windows 2000 都包含了這一功能。 
NAT的分類及工做原理 
解決外網與內網或內網之間的通訊,NAT穿透 - sanerye - DreamEyesSKY 

基本NAT與NAPT如圖5-3所示,NAT分爲兩大類,基本的NAT和NAPT(Network Address/Port Translator)[10][11]。 
基本的NAT,它僅將內網主機的私有IP地址轉換成公網IP地址,但並不將TCP/UDP端口信息進行轉換,有動態與靜態之區分。因爲如今大部分都屬於另外一種類型,即NAPT,故這裏不詳細討論基礎NAT。 
另一種NAT叫作NAPT(Network Address/Port Translator),從名稱上咱們也能夠看得出,NAPT不但會改變通過這個NAT設備的IP數據報的IP地址,還會改變IP數據報的TCP/UDP端口。NAPT的地址及端口的轉換過程,請看圖5-4: 
解決外網與內網或內網之間的通訊,NAT穿透 - sanerye - DreamEyesSKY 
私有網絡中某一主機Client A(10.0.0.2),它的某個進程經過1234端口,想訪問外網服務器18.181.0.31的1235端口。那麼當數據包經過NAT時,這個NAT的外網地址是155.99.25.11,首先NAT會改變這個數據包的原IP地址,改成155.99.25.11。並分配一個端口(如62000)給Client A,把數據包的原端口號改成62000。因此原本是(10.0.0.2:1234->18.181.0.31:1235)的數據包到了互聯網上變爲了(155.99.25.11:62000->18.181.0.31:1235),如圖5-4左圖所示。NAT會記住62000端口對應的是10.0.0.2的1234端口,之後從外網服務器18.181.0.31發送到62000端口的數據會被NAT自動的改變目的IP和端口號,而後轉發到10.0.0.2上(如圖5-4右圖所示) 
錐型NAT與對稱型NAT 
解決外網與內網或內網之間的通訊,NAT穿透 - sanerye - DreamEyesSKY 

NAPT又分爲錐型(Cone)和對稱型(Symmetric),如圖5-5所示,它們的區別在於,在NAT已分配端口號給Client A的狀況下,若是Client A繼續用1235端口與另外一外網服務器通信,錐型NAT還會繼續用原來62000端口,即所分配的端口號不變。而對於對等型NAT,NAT將會分配另外一端口號(如62001)給Client A的1235端口。也就是說,同一內網主機同一端口號,對於錐型NAT,不管與哪一外網主機通信,都不改變所分配的端口號;而對於對等型NAT,同一內網主機同一端口號,每一次與不一樣的外網主機通信,就從新分配另外一個端口號。 
徹底錐型NAT、受限制錐型NAT與端口受限制型NAT 
錐型NAT可另外分類爲徹底錐形(Full Cone)NAT,受限制錐形(Restricted Cone)NAT,端口受限制錐形(Port Restricted Cone)NAT。 
①徹底錐形(Full Cone)NAT 
這種NAT內部的主機A鏈接過外網主機C後,NAT會打開一個端口。而後外網的任何發到這個打開的端口的UDP數據報均可以到達A,不論是不是C發過來的[12]。 
例如 A: 192.168.8.100  NAT: 202.100.100.100  C: 292.88.88.88 
A(192.168.8.100:5000) -> NAT(202.100.100.100:8000) -> C(292.88.88.88:2000) 
任何發送到NAT(202.100.100.100:8000)的數據均可以到達A(192.168.8.100:5000)。 
②受限制錐形(Restricted Cone)NAT 
這種NAT內部的主機A鏈接過外網的主機C後,NAT打開一個端口。而後C能夠用任何端口和A通訊,但其餘的外網主機不能夠。 
例如 A: 192.168.8.100  NAT: 202.100.100.100  C: 292.88.88.88 
A(192.168.8.100:5000) -> NAT(202.100.100.100:8000) -> C(292.88.88.88:2000) 
任何從C發送到NAT(202.100.100.100:8000)的數據均可以到達A(192.168.8.100:5000)。 
③端口受限制錐形(Port Restricted Cone)NAT 
這種NAT內部的主機A鏈接過外網的主機C後,NAT打開一個端口。而後C只能用原來的端口和A通訊,其餘的外網主機不能夠。 
例如 A: 192.168.8.100  NAT: 202.100.100.100  C: 292.88.88.88 
A(192.168.8.100:5000) -> NAT(202.100.100.100:8000) -> C(292.88.88.88:2000) 
只有C(202.88.88.88:2000)發送到 NAT(202.100.100.100:8000)的數據均可以到達A(192.168.8.100:5000)。 
NAT產生的問題 
NAT很好地解決了地址緊缺的問題,屏蔽了內部網絡,但也帶來一些問題。內網的主機向外鏈接是很容易的(NAT至關於透明的,內網的和外網的主機均不用知道NAT的狀況)。但若是外部的計算機想訪問子網內的計算機就比較困難了,這可使內網主機先發起鏈接從而解決問題。可是若是兩臺主機都分別位於兩不一樣NAT後面時,兩臺主機沒法通訊。當分別位於兩不一樣NAT(NAT A,NAT B)後面的兩臺主機A和B欲進行通信時,若主機B主動發起鏈接,它該連哪一個地址呢?第一種狀況:試圖直接連到主機A的內網私有地址(10.0.0.2:1234)確定會失敗,由於10.0.0.2根本就不是一個能夠在公網上路由的IP地址;第二種狀況,試圖直接連到B的NAT公有地址(155.99.25.11:62000),NAT A會拒絕這個數據包,由於這個端口並沒有綁定內網主機的某個端口,或即便有所綁定,但這個端口所綁定的外網地址和端口並非B的地址和端口。若A主動鏈接B,結果同樣。 
有兩種方法解決這個問題。方法一:經過服務器,服務器做爲中間人,轉發主機間的數據。但若用戶數量到達必定數目時,這方法浪費帶寬且給服務器帶來很大壓力,因此方法不可行。方法二,仍是經過服務器,但服務器只充當「介紹人」,不轉發主機間的數據,具體請看下面的「UDP打孔技術」 (UDP hole punching) 
穿透NAT——UDP打孔技術 
所謂的「打孔技術」,就是在內網的NAT設備上打上一個「孔」(也就是在NAT上創建一個會話,綁定地址和端口號),這個孔不能由外部來打,只能由內網內的主機來打。並且這個孔多是有方向的,好比從內部某臺主機(好比:192.168.0.10)向外部的某個IP(好比:219.237.60.1)發送一個UDP包,那麼就在這個內網的NAT設備上打了一個方向爲219.237.60.1的「孔」,之後219.237.60.1就能夠經過這個孔與內網的192.168.0.10聯繫了[13]。 
下面就根據NAT的各類類型詳細解析如何「打孔」,如何穿透NAT。 
1.徹底錐形(Full Cone)NAT 
處於不一樣內網的主機A和主機B,各自先鏈接服務器,從而在各自NAT設備上打開了一個「孔」,服務器收到主機A和主機B的鏈接後,知道A與B的公網地址和NAT分配給它們的端口號,而後把這些NAT地址與端口號告訴A與B,因爲在徹底錐形NAT的特色,A和B給服務器所打開的「孔」,能給別的任何的主機使用。故A與B可鏈接對方的公網地址和端口直接進行通訊。服務器在這裏充當「介紹人」,告訴A與B對方的地址和端口號。 
2.受限制錐形(Restricted Cone)NAT 
A和B仍是要先鏈接服務器,服務器發送A和B的地址和端口信息給A和B,但因爲受限制錐形NAT的特色,他們所打開的「孔」,只能與服務器通訊。要使他們能夠直接通訊,解決辦法以下: 
假如主機A開始發送一個UDP信息到主機B的公網地址上,與此同時,它又經過服務器中轉發送了一個邀請信息給主機B,請求主機B也給主機A發送一個UDP信息到主機A的公網地址上。這時主機A向主機B的公網IP發送的信息致使NAT A打開一個處於主機A的和主機B之間的會話,與此同時,NAT B也打開了一個處於主機B和主機A的會話。一旦這個新的UDP會話各自向對方打開了,主機A和主機B之間就能夠直接通訊了[14]。 
3.端口受限制錐形(Port Restricted Cone)NAT 
對於該類型的NAT,解決辦法跟上面的方法同樣。 
4.對稱型(Symmetric)NAT 
對稱型NAT,對於不一樣的外網主機地址,它都會分配不一樣的端口號,因此進行UDP打孔比較困難,但也能夠進行端口預測打孔,不過不能保證成功。 
以上的穿透NAT,是對NAPT來進行穿透,主要是針對UDP協議。TCP協議也有可能,可是可行性很是小,要求更高。而且,語音視頻通訊是用UDP傳輸的,故針對TCP的NAT穿透在這裏不做討論。基礎NAT不修改通過的數據包的端口號,它們能夠看做是徹底錐形NAT的精簡版本,即基礎NAT也能夠被穿透。NAT設備將在必定時間後關閉UDP的一個映射,因此爲了保持與服務器可以一直通訊,服務器或客戶端必需要週期性地發送UDP包,保持映射不被關閉。 
目前比較經常使用的NAT類型是徹底錐型NAT 
 解決外網與內網或內網之間的通訊,NAT穿透 - sanerye - DreamEyesSKY 
如圖6-7所示,步驟以下: 
①客戶端A發UDP數據報經NAT A,把數據發送到服務器。NAT A分配端口給客戶端A。服務器接收到信息後,把客戶端A經NAT A後的地址及端口信息記錄下來。 
②客戶端B發UDP數據報經NAT B,把數據發送到服務器。NAT B分配端口給客戶端B。服務器接收到信息後,把客戶端B經NAT B後的地址及端口信息記錄下來。 
③ 服務器把客戶端B的地址及端口信息發送給客戶端A,把客戶端A的地址及端口信息發送給客戶端B,客戶端A、B就能夠經過所得到的對方的地址及端口號進行通訊了。服務器

相關文章
相關標籤/搜索