1. 程式人生 > >腦殘式網路程式設計入門(六):什麼是公網IP和內網IP?NAT轉換又是什麼鬼?

腦殘式網路程式設計入門(六):什麼是公網IP和內網IP?NAT轉換又是什麼鬼?

本文引用了“帥地”發表於公眾號苦逼的碼農的技術分享。

1、引言

搞網路通訊應用開發的程式設計師,可能會經常聽到外網IP(即網際網路IP地址)和內網IP(即區域網IP地址),但他們的區別是什麼?又有什麼關係呢?另外,內行都知道,提到外網IP和內網IP就不得不提NAT路由轉換這種東西,那這雙是什麼鬼?本文就來簡單講講這些到底都是怎麼回事。

另外,以下是與本文內相關知識點有關聯的文章,可詳細閱讀之:

P2P 技術詳解(一):NAT詳解——詳細原理、P2P簡介

P2P 技術詳解(二):P2P中的NAT穿越(打洞)方案詳解

通俗易懂:快速理解P2P技術中的NAT穿透原理

網路程式設計懶人入門(六):史上最通俗的集線器、交換機、路由器功能原理入門

網路程式設計懶人入門(九):通俗講解,有了IP地址,為何還要用MAC地址?

腦殘式網路程式設計入門(五):每天都在用的Ping命令,它到底是什麼?

學習交流:

- 即時通訊開發交流3群:185926912[推薦]

- 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM

(本文同步釋出於:http://www.52im.net/thread-2082-1-1.html

2、系列文章

本文是系列文章中的第6篇,本系列大綱如下:

腦殘式網路程式設計入門(一):跟著動畫來學TCP三次握手和四次揮手》(本文)

腦殘式網路程式設計入門(二):我們在讀寫Socket時,究竟在讀寫什麼?

腦殘式網路程式設計入門(三):HTTP協議必知必會的一些知識

腦殘式網路程式設計入門(四):快速理解HTTP/2的伺服器推送(Server Push)

腦殘式網路程式設計入門(五):每天都在用的Ping命令,它到底是什麼?

腦殘式網路程式設計入門(六):什麼是公網IP和內網IP?NAT轉換又是什麼鬼?

3、每臺電腦都必須要一個公網IP嗎?

答案:不是。

我們都知道,IPv4中的IP地址的數量是有限的(所以現在都在搞IPv6嘛),每次把一部分地址分配出去,那麼就意味著能夠用來分配的IP地址就更少了,而且隨著現在手機,電腦等的快速發展,如果每個手機或者電腦都要求一個IP地址,那麼顯然IP地址是不夠用的。

為了解決這個問題,我們可以採取這樣的策略:例如對於一個公司來說,每個公司都會有一個屬於自己公司的內網(也可以稱之為區域網)。

內網(學名應叫區域網(Local Area Network,LAN))是在一個區域性的地理範圍內,一般可以是是幾米內(比如家庭內網),也可以是方圓幾千米以內(比如一個大學內網),將各種計算機、外部裝置和資料庫等互相聯接起來組成的計算機通訊網。

內網主要作用有:

1)共享傳輸通道:簡單地理解就是不需要每臺電腦一個外網IP地址;

2)傳輸速率高:內網之間的電腦因為沒有外網網路拓撲的複雜性,所以互相通訊的網路可以很快,比如從一個臺電腦向另一臺電腦複製一個幾G的檔案可能只需要數十秒時間。

3)誤位元速率低:因為通訊距離很近,所以誤位元速率很低,換句話說就是網路很穩定(老一點的程式設計師都知道,讀大學的時候同一個宿舍內網聯網玩C/S遊戲,幾乎不會遇到斷網或卡頓的事情,除非有人下毛片或者把網路給拔了,哈哈)。

4、公司的內網是如何實現內網IP地址分配和管理的?

假如我們給這個公司A分配了一個IP=192.168.1.1。我們把這個IP作為這個公司內網的閘道器吧。

在公司A的內網裡面有3臺電腦,如果這三臺電腦要上網的話,我們需要給他分配一個IP,那麼就像上一節提到的:我們一定需要去申請3個IP地址來使用嗎?

答否。我們不一定需要去申請3個IP的,在我們這個內網裡,我們可以指定自己的規則,例如,我們可以給這三臺電腦隨便分配三個IP(請注意,這三個IP不是去申請的,而且我自己隨意給它分配的)。分別分配電腦A = 192.168.1.2   電腦B = 192.168.1.3 電腦C = 192.168.1.4。

而這個規則可以由我們的內網閘道器來管理,就像下面這樣:

5、NAT技術:實現內網電腦訪問外網的能力

假如電腦A想要訪問百度,百度的IP我們假設為:172.168.30.3:

我們都知道,電腦A的IP是我們虛構的,實際上可能並不存在這樣一個IP,如果用電腦A的IP去訪問百度,那肯定行不通。

我們也知道,由於百度和電腦A不在一個區域網內,所以A要訪問百度,那麼必須得經過閘道器。而閘道器的這個IP地址,是真實存在的,是可以訪問百度的。

為了讓 A 可以訪問百度,那麼我們可以採取這樣的方法:讓閘道器去幫助 A 訪問,然後百度把結果傳遞給閘道器,而閘道器再把結果傳遞給 A,這樣不就可以解決了?

不過電腦A、B、C都可能拜託閘道器去幫忙訪問百度,而百度返回的結果 的目的IP都是閘道器的IP=192.168.1.1。那麼閘道器該如何進行區分這結果是A的、B的還是C的呢?

我們去訪問百度的時候,不是需要指定一個埠嗎?只要我們把 A的IP + 埠  對映成  閘道器的IP+埠,不就可以唯一確定身份了?

例如A用埠60去訪問百度,閘道器把   A的IP+埠60    對映成     閘道器的IP+埠80 不就可以了?

百度把結果返回給閘道器的80埠之後,閘道器再通過對映表,就可以把結果返回給 A的60埠 了。

如果B也是用60埠去訪問百度的話,也是一樣,可以把它對映到90埠。

這種方法地址的對映轉換,我們也稱之為網路地址轉換,英文為 Network Address Translation,簡稱NAT。

而像A、B、C這樣的IP地址我們也稱之為內網IP,即內網IP;而像閘道器,百度這樣的IP我們稱之為外網IP(即網際網路公網IP)。

所以,一個典型的內網訪問公網的原理,就像下圖這樣就可以實現了:

現在知道外網IP和內網IP了吧?

6、本文小結

為了解決IP地址短缺,技術專家們發明了內網技術,而內網技術的理論支撐就是NAT技術,所以搞網路通訊的程式設計師非常有必要對NAT技術有一個深入的理解。

如果你想詳細瞭解NAT路由轉換技術,不防從下面幾篇文章開始:

P2P 技術詳解(一):NAT詳解——詳細原理、P2P簡介

P2P 技術詳解(二):P2P中的NAT穿越(打洞)方案詳解

通俗易懂:快速理解P2P技術中的NAT穿透原理

網路程式設計懶人入門(六):史上最通俗的集線器、交換機、路由器功能原理入門

幾點需要注意的地方:

1)對於全球IP,顯然每個IP都是唯一的,而對於私有IP,同一個區域網內,也得是唯一的,但在兩個不同的區域網中,是可以有相同的私有IP的;

2)區域網內主機之間的通訊,是不需要進行地址轉換的,而如果需要訪問外網,才需要進行地址轉換。

實際上,我們也可以把這種地址轉換稱之為一種代理。閘道器就相當於一個代理,把區域網內的主機的一些資訊都給隱藏了起來。就像本內裡所描述的那樣,百度並不知道是主機A訪問它,他只知道是閘道器訪問了它。

附錄:更多網路程式設計方面的文章

[1] 網路程式設計基礎資料:

TCP/IP詳解 - 第11章·UDP:使用者資料報協議

TCP/IP詳解 - 第17章·TCP:傳輸控制協議

TCP/IP詳解 - 第18章·TCP連線的建立與終止

TCP/IP詳解 - 第21章·TCP的超時與重傳

技術往事:改變世界的TCP/IP協議(珍貴多圖、手機慎點)

通俗易懂-深入理解TCP協議(上):理論基礎

通俗易懂-深入理解TCP協議(下):RTT、滑動視窗、擁塞處理

理論經典:TCP協議的3次握手與4次揮手過程詳解

理論聯絡實際:Wireshark抓包分析TCP 3次握手、4次揮手過程

計算機網路通訊協議關係圖(中文珍藏版)

UDP中一個包的大小最大能多大?

P2P技術詳解(一):NAT詳解——詳細原理、P2P簡介

P2P技術詳解(二):P2P中的NAT穿越(打洞)方案詳解

P2P技術詳解(三):P2P技術之STUN、TURN、ICE詳解

通俗易懂:快速理解P2P技術中的NAT穿透原理

高效能網路程式設計(一):單臺伺服器併發TCP連線數到底可以有多少

高效能網路程式設計(二):上一個10年,著名的C10K併發連線問題

高效能網路程式設計(三):下一個10年,是時候考慮C10M併發問題了

高效能網路程式設計(四):從C10K到C10M高效能網路應用的理論探索

高效能網路程式設計(五):一文讀懂高效能網路程式設計中的I/O模型

高效能網路程式設計(六):一文讀懂高效能網路程式設計中的執行緒模型

不為人知的網路程式設計(一):淺析TCP協議中的疑難雜症(上篇)

不為人知的網路程式設計(二):淺析TCP協議中的疑難雜症(下篇)

不為人知的網路程式設計(三):關閉TCP連線時為什麼會TIME_WAIT、CLOSE_WAIT

不為人知的網路程式設計(四):深入研究分析TCP的異常關閉

不為人知的網路程式設計(五):UDP的連線性和負載均衡

不為人知的網路程式設計(六):深入地理解UDP協議並用好它

不為人知的網路程式設計(七):如何讓不可靠的UDP變的可靠?

網路程式設計懶人入門(一):快速理解網路通訊協議(上篇)

網路程式設計懶人入門(二):快速理解網路通訊協議(下篇)

網路程式設計懶人入門(三):快速理解TCP協議一篇就夠

網路程式設計懶人入門(四):快速理解TCP和UDP的差異

網路程式設計懶人入門(五):快速理解為什麼說UDP有時比TCP更有優勢

網路程式設計懶人入門(六):史上最通俗的集線器、交換機、路由器功能原理入門

網路程式設計懶人入門(七):深入淺出,全面理解HTTP協議

網路程式設計懶人入門(八):手把手教你寫基於TCP的Socket長連線

網路程式設計懶人入門(九):通俗講解,有了IP地址,為何還要用MAC地址?

技術掃盲:新一代基於UDP的低延時網路傳輸層協議——QUIC詳解

讓網際網路更快:新一代QUIC協議在騰訊的技術實踐分享

現代移動端網路短連線的優化手段總結:請求速度、弱網適應、安全保障

聊聊iOS中網路程式設計長連線的那些事

移動端IM開發者必讀(一):通俗易懂,理解行動網路的“弱”和“慢”

移動端IM開發者必讀(二):史上最全移動弱網路優化方法總結

IPv6技術詳解:基本概念、應用現狀、技術實踐(上篇)

IPv6技術詳解:基本概念、應用現狀、技術實踐(下篇)

從HTTP/0.9到HTTP/2:一文讀懂HTTP協議的歷史演變和設計思路

以網遊服務端的網路接入層設計為例,理解實時通訊的技術挑戰

邁向高階:優秀Android程式設計師必知必會的網路基礎

>> 更多同類文章 ……

[2] NIO非同步網路程式設計資料:

Java新一代網路程式設計模型AIO原理及Linux系統AIO介紹

有關“為何選擇Netty”的11個疑問及解答

開源NIO框架八卦——到底是先有MINA還是先有Netty?

選Netty還是Mina:深入研究與對比(一)

選Netty還是Mina:深入研究與對比(二)

NIO框架入門(一):服務端基於Netty4的UDP雙向通訊Demo演示

NIO框架入門(二):服務端基於MINA2的UDP雙向通訊Demo演示

NIO框架入門(三):iOS與MINA2、Netty4的跨平臺UDP雙向通訊實戰

NIO框架入門(四):Android與MINA2、Netty4的跨平臺UDP雙向通訊實戰

Netty 4.x學習(一):ByteBuf詳解

Netty 4.x學習(二):Channel和Pipeline詳解

Netty 4.x學習(三):執行緒模型詳解

Apache Mina框架高階篇(一):IoFilter詳解

Apache Mina框架高階篇(二):IoHandler詳解

MINA2 執行緒原理總結(含簡單測試例項)

Apache MINA2.0 開發指南(中文版)[附件下載]

MINA、Netty的原始碼(線上閱讀版)已整理髮布

解決MINA資料傳輸中TCP的粘包、缺包問題(有原始碼)

解決Mina中多個同類型Filter例項共存的問題

實踐總結:Netty3.x升級Netty4.x遇到的那些坑(執行緒篇)

實踐總結:Netty3.x VS Netty4.x的執行緒模型

詳解Netty的安全性:原理介紹、程式碼演示(上篇)

詳解Netty的安全性:原理介紹、程式碼演示(下篇)

詳解Netty的優雅退出機制和原理

NIO框架詳解:Netty的高效能之道

Twitter:如何使用Netty 4來減少JVM的GC開銷(譯文)

絕對乾貨:基於Netty實現海量接入的推送服務技術要點

Netty乾貨分享:京東京麥的生產級TCP閘道器技術實踐總結

新手入門:目前為止最透徹的的Netty高效能原理和框架架構解析

>> 更多同類文章 ……

(本文同步釋出於:http://www.52im.net/thread-2082-1-1.html