1. 程式人生 > >NAT路由器“打洞”技術,即P2P通訊實現原理(非常詳細)

NAT路由器“打洞”技術,即P2P通訊實現原理(非常詳細)

什麼是打洞,為什麼要打洞

由於Internet的快速發展 IPV4地址不夠用,不能每個主機分到一個公網IP 所以使用NAT地址轉換。

下面是我在網上找到的一副圖

一般來說都是由私網內主機(例如上圖中“電腦A-01”)主動發起連線,資料包經過NAT地址轉換後送給公網上的伺服器(例如上圖中的“Server”),連線建立以後可雙向傳送資料,NAT裝置允許私網內主機主動向公網內主機發送資料,但卻禁止反方向的主動傳遞,但在一些特殊的場合需要不同私網內的主機進行互聯(例如P2P軟體、網路會議、視訊傳輸等),TCP穿越NAT的問題必須解決。

下面是NAT的幾種型別

NAT裝置的型別對於TCP穿越NAT,有著十分重要的影響,根據埠對映方式,NAT可分為如下4類,前3種NAT型別可統稱為cone型別。
(1)全克隆( Full Clone) : NAT把所有來自相同內部IP地址和埠的請求對映到相同的外部IP地址和埠。任何一個外部主機均可通過該對映傳送IP包到該內部主機。
(2)限制性克隆(Restricted Clone) : NAT把所有來自相同內部IP地址和埠的請求對映到相同的外部IP地址和埠。但是,只有當內部主機先給IP地址為X的外部主機發送IP包,該外部主機才能向該內部主機發送IP包。
(3)埠限制性克隆( Port Restricted Clone) :埠限制性克隆與限制性克隆類似,只是多了埠號的限制,即只有內部主機先向IP地址為X,埠號為P的外部主機發送1個IP包,該外部主機才能夠把源埠號為P的IP包傳送給該內部主機。
(4)對稱式NAT ( Symmetric NAT) :這種型別的NAT與上述3種類型的不同,在於當同一內部主機使用相同的埠與不同地址的外部主機進行通訊時, NAT對該內部主機的對映會有所不同。對稱式NAT不保證所有會話中的私有地址和公開IP之間繫結的一致性。相反,它為每個新的會話分配一個新的埠號。

先假設:有一個伺服器S在公網上有一個IP,兩個私網分別由NAT-A和NAT-B連線到公網,NAT-A後面有一臺客戶端A,NAT-B後面有一臺客戶端B,現在,我們需要藉助S將A和B建立直接的TCP連線,即由B向A打一個洞,讓A可以沿這個洞直接連線到B主機,就好像NAT-B不存在一樣。

實現過程如下:
1、 S啟動兩個網路偵聽,一個叫【主連線】偵聽,一個叫【協助打洞】的偵聽。
2、 A和B分別與S的【主連線】保持聯絡。
3、 當A需要和B建立直接的TCP連線時,首先連線S的【協助打洞】埠,併發送協助連線申請。同時在該埠號上啟動偵聽。注意由於要在相同的網路終端上繫結到不同的套接字上,所以必須為這些套接字設定 SO_REUSEADDR 屬性(即允許重用),否則偵聽會失敗。
4、 S的【協助打洞】連線收到A的申請後通過【主連線】通知B,並將A經過NAT-A轉換後的公網IP地址和埠等資訊告訴B。
5、 B收到S的連線通知後首先與S的【協助打洞】埠連線,隨便傳送一些資料後立即斷開,這樣做的目的是讓S能知道B經過NAT-B轉換後的公網IP和埠號。
6、 B嘗試與A的經過NAT-A轉換後的公網IP地址和埠進行connect,根據不同的路由器會有不同的結果,有些路由器在這個操作就能建立連線,大多數路由器對於不請自到的SYN請求包直接丟棄而導致connect失敗,但NAT-A會紀錄此次連線的源地址和埠號,為接下來真正的連線做好了準備,這就是所謂的打洞,即B向A打了一個洞,下次A就能直接連線到B剛才使用的埠號了。
7、 客戶端B打洞的同時在相同的埠上啟動偵聽。B在一切準備就緒以後通過與S的【主連線】回覆訊息“我已經準備好”,S在收到以後將B經過NAT-B轉換後的公網IP和埠號告訴給A。
8、 A收到S回覆的B的公網IP和埠號等資訊以後,開始連線到B公網IP和埠號,由於在步驟6中B曾經嘗試連線過A的公網IP地址和埠,NAT-A紀錄了此次連線的資訊,所以當A主動連線B時,NAT-B會認為是合法的SYN資料,並允許通過,從而直接的TCP連線建立起來了。