首先文章建議 Cone NAPT 還有但願,要是 Symmetri NAPT 就別想了,接着介紹了兩種基本狀況,一是一臺內網機器鏈接外網通訊的狀況,二是兩臺內網之間互聯的狀況。html
第一種,只須要內網主動發起鏈接就能夠了。內網機器A(192.168.1.x:4000)要求鏈接外網服務端S(60.17.211.x:5000),發出鏈接請求後被A網所在網關NA(10.11.12.x)獲取,NA將A的地址轉變爲其自身地址,並分配臨時端口(6000)用做通信,因而,當初的 A->S 就變成如今的 A->NA->S。那麼S接到請求後看到的並非A的地址,而是NA的IP和Port,此時S若是照着此地址回覆,則NA收到,由於NA此時有通信臨時Session被建立了,因此在必定時間內(貌似根據不一樣硬件、軟件設備而不一樣)還記得發到6000的信息要轉給A,NA就會轉發給A。至此,通信成功。安全
第二種,兩個內網之間就要複雜一些,有一個圖很好,我轉載了一下,特別聲明,是從百度文庫截圖下來的。網絡
這個圖很清晰,作個簡單備註就能夠了。session
首先,兩個內網A和B誰都不能直接連誰,因此第一次,都是給S發送登陸、心跳之類的,目的是代表本身的存在,並創建session,固然,這個過程仍是經過自身網絡的N實現的。那麼,如何作到UDP穿透呢?post
1. 假設左邊的爲A(192.168.1.77:8000),A->NA(211.133.*:6000)->S,此時,S記住了 A 的存在,NA也與A創建了對應關係(發到6000的信息就是A的),同樣道理,B也與S創建了鏈接。htm
2. A經過S知道了B的存在(只是知道存在),A想連B,因而A告訴S,「讓B探測我一下」blog
3. S把A的要求發給B,因而B發送「探測」包給A,事實上就是 B->NB->NA,可是由於 NA 不認識 NB(以前沒聯繫過),因此 NA 就不會轉發給 A,隨之丟棄。可是 NB 上已經創建起了目的是 NA 的 session,這是後面打洞成功的關鍵一步。io
4. B 發送探測給 A 以後,由於 NA 一定丟棄,因此 B 向 S 發送「反饋包」,就是圖中的步驟 4,目的是告訴 S 已經發送過探測包給 A 了。這一步的目的是,借 S 之手告訴 A ,我已經聯繫過你了,我已經有了關於你的 session 。登錄
5. S 通知 A:「人家 B 已經聯繫過你了」。百度
6. A 知道以後,發送數據包給 B ,也就是 A->NA->NB->B。當 NA->NB 時,由於 NB 存有當初連接 NA 的信息,因此 NB 認爲它本身認識 NA ,會接受 NA 發送的信息,轉發給 B,至此,理論上,打洞完成。AB之間能夠互通了。還未通過本身試驗,不知道對不對。
圖中右上角步驟2中的文字「...給NAT211.134.*」應該是錯誤的,正確的應該是「211.133.*」,由於是 S 讓 B 去鏈接 A,而 A 的地址是 211.133.*,另外還有幾點疑惑和說明的地方
1. 「信息不請自來,NAT 安全起見,是會被丟棄的」——A->NA->S 時,NA 接到請求會建立 session ,分配某端口如6000對應 A ,目的是接到發到 6000 端口上的信息就知道轉發給 A,但只會接受當初 A 所請求的遠程主機 S 所發過來的信息纔會轉發給 A,其它地址則會丟棄。這也是爲何兩個內網不能直接互發的緣由,舉個例子就是洞還沒打,外界發過來的信息,也會被看門人 NA 給扔掉,因 NA 那有一個記錄表,A 曾經要求鏈接 S,這條記錄就會有關於 S 的信息,好比另外一臺 S2 發過來一樣的 6000 端口信息,因爲 NA 沒有記錄不認識 S2 ,是會丟棄不會轉發的。
2. 打洞要從內部向外部打,S 想鏈接 A,A 向 S 打洞(發起鏈接)。A 想鏈接 B,要經過 S 告訴 B 讓 B 向 A 打洞,B 打完 A 沿此路打回去,才能成功。
出處:http://www.cnblogs.com/wzsblogs/p/5341078.html