p2p之NAT穿透

什么是NAT

NAT(Network Address Translation)类垦,網(wǎng)絡(luò)地址轉(zhuǎn)換。是1994年提出的。當(dāng)在專用網(wǎng)內(nèi)部的一些主機(jī)本來已經(jīng)分配到了本地IP地址(即僅在本專用網(wǎng)內(nèi)使用的專用地址),但現(xiàn)在又想和因特網(wǎng)上的主機(jī)通信(并不需要加密)時(shí)锋叨,可使用NAT方法。
搓译。裝有NAT軟件的路由器叫做NAT路由器悲柱,它至少有一個(gè)有效的外部全球IP地址。這樣些己,所有使用本地地址的主機(jī)在和外界通信時(shí)豌鸡,都要在NAT路由器上將其本地地址轉(zhuǎn)換成全球IP地址,才能和因特網(wǎng)連接段标。
同樣還有NAPT涯冠,網(wǎng)絡(luò)地址、端口轉(zhuǎn)換”婆樱現(xiàn)在一般穿透規(guī)則就是通過獲取ip蛇更、端口來實(shí)現(xiàn)的,重點(diǎn)是實(shí)現(xiàn)穿透,所以以下統(tǒng)稱NAT即可派任。

為什么要穿透NAT

NAT可以有效的減緩全球IP枯竭的問題砸逊。但是同時(shí)NAT也屏蔽了內(nèi)部設(shè)備。

比如在局域網(wǎng)A下有一個(gè)內(nèi)網(wǎng)IP地址為192.168.1.155的設(shè)備A掌逛,現(xiàn)在一個(gè)設(shè)備B想要訪問這個(gè)設(shè)備A师逸,根據(jù)設(shè)備B所在網(wǎng)絡(luò)可分為一下情況。

  • 設(shè)備B同在局域網(wǎng)A中:
    設(shè)備B可直接通過設(shè)備內(nèi)網(wǎng)ip 192.168.1.155 地址訪問設(shè)備A豆混;
  • 設(shè)備B在外網(wǎng):
    設(shè)備B無法通過設(shè)備A內(nèi)網(wǎng)訪問設(shè)備A篓像;
  • 設(shè)備B在不同局域網(wǎng)A的局域網(wǎng)B中:
    設(shè)備B在通過ip 192.168.1.155 訪問的時(shí)候可能訪問到局域網(wǎng)B下內(nèi)網(wǎng)IP也為192.168.1.155的設(shè)備C,也可能找不到該ip皿伺,但是無法訪問設(shè)備A员辩。

這就是為什么在內(nèi)網(wǎng)建立一個(gè)tcp或者udp服務(wù),內(nèi)網(wǎng)客戶端可以通過ip和端口號(hào)直接通信鸵鸥,而外網(wǎng)卻無法訪問該內(nèi)網(wǎng)建立的服務(wù)奠滑。
要實(shí)現(xiàn)p2p(Peer to Peer),首先我們的要知道客戶端ip和端口號(hào)脂男,但是通過局域網(wǎng)路由器的NAT轉(zhuǎn)換养叛,生成的外網(wǎng)ip和端口我們無法預(yù)知,這樣我們就無法建立p2p連接宰翅。

NAPT轉(zhuǎn)換

如果你還是不明白NAT為什么屏蔽了內(nèi)部設(shè)備,接下來舉個(gè)NAT轉(zhuǎn)換例子就明白了爽室。
例:
內(nèi)網(wǎng)機(jī)器A ip(192.168.1.188) 端口(9999) - 訪問外網(wǎng)目標(biāo)主機(jī)B ip(220.233.28.42) 端口(8888):

1.數(shù)據(jù)包

目的主機(jī):220.233.28.42
目的端口:8888

源主機(jī):192.168.1.188
源端口:9999 (用戶自定義或隨機(jī))

2.地址轉(zhuǎn)換

目的主機(jī):220.233.28.42
目的端口:8888

源主機(jī):123.206.41.242 (NAPT轉(zhuǎn)換汁讼,為路由器外網(wǎng)ip)
源端口:17309 (NAPT轉(zhuǎn)換)

3.記錄地址映射

192.168.1.188:9999 ---- 123.206.41.242:17309

4.外網(wǎng)主機(jī)B向內(nèi)網(wǎng)主機(jī)A返回響應(yīng)消息

目的主機(jī):123.206.41.242
目的端口:17309

源主機(jī):220.233.28.42
源端口:8888

5.NAPT查找地址映像并轉(zhuǎn)換

目的主機(jī):192.168.1.188
目的端口:9999

源主機(jī):220.233.28.42
源端口:8888

通過地址轉(zhuǎn)換,主機(jī)A的內(nèi)網(wǎng)地址被映射之后我們是無法預(yù)知的阔墩,而且我們無法通過主機(jī)A的內(nèi)網(wǎng)地址直接訪問A嘿架,所以NAT屏蔽了主機(jī)A。

通過例子可以看到啸箫,當(dāng)主機(jī)A訪問外網(wǎng)主機(jī)B時(shí)耸彪,通過NAT隨機(jī)分配一個(gè)(外網(wǎng)ip為路由器外網(wǎng)ip)端口,這樣就把內(nèi)網(wǎng)地址映射成了一個(gè)唯一的外網(wǎng)地址忘苛。然后外網(wǎng)主機(jī)B響應(yīng)主機(jī)A時(shí)蝉娜,主機(jī)B不直接訪問主機(jī)A,而是通過NAT轉(zhuǎn)換后的地址訪問路由器扎唾,路由器就會(huì)通過映射把數(shù)據(jù)分配給內(nèi)網(wǎng)主機(jī)A召川。這也就是NAT穿透的原理。

NAPT穿透原理

通過雙方所在網(wǎng)絡(luò)環(huán)境不同可分為一下模式:

  • 一個(gè)在局域網(wǎng)胸遇,另一個(gè)在外網(wǎng)
  • 都在不同的局域網(wǎng)
  • 都在相同的局域網(wǎng)

上一章節(jié)已經(jīng)提到了一種穿透方式荧呐,即:局域網(wǎng)-外網(wǎng)的訪問模式,因?yàn)橹鳈C(jī)B在外網(wǎng),ip端口確定倍阐,主機(jī)A可以直接通過B的外網(wǎng)地址訪問B概疆,外網(wǎng)主機(jī)B首先接受到了主機(jī)A的數(shù)據(jù)包,便可以知道主機(jī)A經(jīng)過NAT轉(zhuǎn)化后的外網(wǎng)地址峰搪,然后就可以進(jìn)行相互通信届案。
但是如果雙方都在不同的局域網(wǎng),互相都不知道自己的外網(wǎng)地址怎么辦罢艾。
這種情況就需要利用一個(gè)擁有唯一IP的中間服務(wù)器S楣颠,因?yàn)镾 ip固定并且已知,就讓兩個(gè)設(shè)備都向S發(fā)送數(shù)據(jù)包咐蚯,S就可以的知道兩個(gè)設(shè)備的公網(wǎng)ip童漩,在設(shè)備p2p通信之前先去服務(wù)器查找對(duì)方的ip、端口春锋,就可以實(shí)現(xiàn)通信矫膨。
兩個(gè)設(shè)備同時(shí)處在同一個(gè)局域網(wǎng)下,可以不通過NAT期奔,直接用內(nèi)網(wǎng)ip進(jìn)行通信侧馅,這是最節(jié)省帶寬的方式。當(dāng)然呐萌,也可以通過第二種馁痴,通過S服務(wù)器來得到外網(wǎng)ip端口,這種情況外網(wǎng)的IP是相同的(同一個(gè)路由器)肺孤,只是分配的端口不同罗晕。

發(fā)送數(shù)據(jù)的方式利用UDP,雖然UDP不可靠赠堵,但是UDP可以輕松實(shí)現(xiàn)穿透小渊。通過瀏覽各大博客,都沒有找到通過TCP實(shí)現(xiàn)穿透的項(xiàng)目茫叭,甚至有人說TCP幾乎不可能實(shí)現(xiàn)穿透(博主初學(xué)酬屉,還望指點(diǎn))。

使用過UDP的肯定知道揍愁,首先創(chuàng)建一個(gè)UDP監(jiān)聽端口呐萨,然后可以通過這個(gè)端口發(fā)送和接收數(shù)據(jù)包。NAT會(huì)把這個(gè)監(jiān)聽端口映射為外網(wǎng)ip和端口吗垮。我們只需要通過端口發(fā)送數(shù)據(jù)包給服務(wù)器就可以讓服務(wù)器拿到這個(gè)端口信息垛吗,然后可以讓其他客戶機(jī)通過這個(gè)端口的信息來發(fā)送數(shù)據(jù)給該端口。

在這里NAPT對(duì)UDP的端口映射(session)還有一定的規(guī)則:

  • A.源地址(內(nèi)網(wǎng)ip)不相同烁登,忽略其他因素怯屉,則session不同蔚舀。
  • B.源地址相同,源端口不同锨络,忽略其他因素赌躺,則session不同。
  • C.源地址相同羡儿,源端口相同礼患,目標(biāo)地址不同,對(duì)于不同的NAPT掠归,session可能不同缅叠。(一般大部分是相同的,不同的無法進(jìn)行穿透)
  • D.源地址相同虏冻,源端口相同肤粱,目標(biāo)地址相同,任何端口厨相,session一定相同领曼。

session并不是長(zhǎng)期存在的,不同的路由器session儲(chǔ)存時(shí)間不同蛮穿,短的有的幾十秒庶骄,長(zhǎng)的可能有的幾分種。要想維持這個(gè)session可以通過心跳包來維持践磅,比如10秒向服務(wù)器發(fā)送一個(gè)心跳包单刁。并且對(duì)于上面第三種情況,如果最后session不同音诈,就無法實(shí)現(xiàn)穿透(這種類型一般少見)幻碱。

NAT穿透UDP具體實(shí)現(xiàn)

本來是打算把我的java代碼黏貼出來的,后來想了想细溅,我寫的只是其中一種實(shí)現(xiàn)方式,不同語言也有不同的實(shí)現(xiàn)方式儡嘶,我就來說說實(shí)現(xiàn)的步驟喇聊,就不再寫代碼了。也挺簡(jiǎn)單的蹦狂。

  1. 客戶端建立一個(gè)UDP監(jiān)聽端口
  2. 客戶端做一個(gè)心跳包向服務(wù)器發(fā)送數(shù)據(jù)包
  3. 服務(wù)器接收到心跳包后誓篱,儲(chǔ)存客戶端的ip、端口信息

當(dāng)客戶端要進(jìn)行p2p通信的時(shí)候

  1. 發(fā)送方服務(wù)器查詢接收方ip凯楔、端口
  2. 數(shù)據(jù)包定向ip窜骄、端口發(fā)送數(shù)據(jù)包
  3. 完成通信

注意 重點(diǎn)

到此,你以為結(jié)束了摆屯? 那就大錯(cuò)特錯(cuò)了邻遏。
到這里你會(huì)發(fā)現(xiàn),接收方(以下統(tǒng)稱A)可能拿不到數(shù)據(jù)包,這種情況出現(xiàn)在接收方在局域網(wǎng)內(nèi)(需要穿透NAT)准验。
前面講的赎线,并不是僅僅獲取到設(shè)備外網(wǎng)地址就可以成功穿透,還要注意NAT會(huì)把不認(rèn)識(shí)的數(shù)據(jù)丟棄糊饱。
這是為什么垂寥?
NAT丟棄了你這個(gè)來源不明的包,根本沒有分發(fā)給接收設(shè)備A另锋。
為什么叫來源不明呢滞项,這是因?yàn)槭紫華的UDP端口給服務(wù)器發(fā)數(shù)據(jù)包,A的NAT創(chuàng)建了一個(gè)session夭坪,這樣A再接收到服務(wù)器的數(shù)據(jù)時(shí)文判,會(huì)查找這個(gè)映射(A<--->服務(wù)器),這個(gè)映射就儲(chǔ)存在這個(gè)session里台舱。但是發(fā)送方(B)向A的NAT發(fā)送數(shù)據(jù)(這是在B的NAT建立對(duì)A的映射)律杠,沒有指向B的映射,所以數(shù)據(jù)包被A的NAT丟棄竞惋。
那怎么解決呢柜去,其實(shí)讓A也向B發(fā)一個(gè)數(shù)據(jù)包就好了,這樣A的NAT會(huì)建立一個(gè)對(duì)B的session拆宛,這樣再收到B的數(shù)據(jù)NAT就可以查找到對(duì)應(yīng)的映射了嗓奢。

之前提到的NAPT對(duì)UDP的session映射,源地址相同浑厚,源端口相同股耽,目標(biāo)地址不同,對(duì)于不同的NAPT钳幅,session可能不同物蝙。這條規(guī)則是依據(jù)不同的NAT的。Symmetric NAPT會(huì)導(dǎo)致session不同敢艰,Cone NAPT則是相同的诬乞。對(duì)于p2p只要一方使用的是Symmetric NAPT就會(huì)導(dǎo)致無法穿透。具體可自行百度钠导。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末震嫉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子牡属,更是在濱河造成了極大的恐慌票堵,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逮栅,死亡現(xiàn)場(chǎng)離奇詭異悴势,居然都是意外死亡窗宇,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門瞳浦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來担映,“玉大人,你說我怎么就攤上這事叫潦∮辏” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵矗蕊,是天一觀的道長(zhǎng)短蜕。 經(jīng)常有香客問我,道長(zhǎng)傻咖,這世上最難降的妖魔是什么朋魔? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮卿操,結(jié)果婚禮上警检,老公的妹妹穿的比我還像新娘。我一直安慰自己害淤,他們只是感情好扇雕,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著窥摄,像睡著了一般镶奉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上崭放,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天哨苛,我揣著相機(jī)與錄音,去河邊找鬼币砂。 笑死建峭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的决摧。 我是一名探鬼主播迹缀,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蜜徽!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起票摇,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤拘鞋,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后矢门,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體盆色,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡灰蛙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了隔躲。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摩梧。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖宣旱,靈堂內(nèi)的尸體忽然破棺而出仅父,到底是詐尸還是另有隱情,我是刑警寧澤浑吟,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布笙纤,位于F島的核電站,受9級(jí)特大地震影響组力,放射性物質(zhì)發(fā)生泄漏省容。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一燎字、第九天 我趴在偏房一處隱蔽的房頂上張望腥椒。 院中可真熱鬧,春花似錦候衍、人聲如沸笼蛛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽伐弹。三九已至,卻和暖如春榨为,著一層夾襖步出監(jiān)牢的瞬間惨好,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工随闺, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留日川,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓矩乐,卻偏偏與公主長(zhǎng)得像龄句,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子散罕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容