目錄
背景補充
協議頭格式
IP報文的分片與組裝
網段劃分
網段劃分是什么?為什么要進行網段劃分?
怎么進行網段劃分?
路由
路由表生成算法
背景補充
假設現在主機B要給主機C發送消息。在我們前面的學習中,一直都是將數據拷貝到主機B的發送緩沖區,然后通過網絡,到達主機C,將報頭分離,數據拷貝到接收緩沖區。對于數據在網絡中的過程,我們是沒有進行介紹的。我們要知道,主機B和主機C并不是直接連接的。中間是會經過非常多的路由器的。對于整個傳輸過程,此時會有2個問題:
1.路徑選擇問題。主機B為什么要將報文發送給路由器F呢?路由器F又為什么要將這個報文發送給路由器G呢?...目標決定路徑,因為主機B要將報文發送給主機C。所以,這里就需要引入一個概念---IP地址,這里所說的IP地址是在全球范圍都具有唯一性的IP地址。現在主機C的IP地址是確定且唯一的,未來主機B就可以根據主機C的IP地址,通過某種策略來進行路徑選擇。所以,路徑選擇的一個重要依據就是目標主機的IP地址。
2.主機B怎么將報文交給路由器F?主機B要將報文交給路由器F,則主機B和路由器F一定是處于同一個子網的,因為在同一個子網下是可以直接通信的。所以,主機B與主機C通信時,是通過無數的子網構成的信道通信的。
第一個問題是網絡層的問題,第二個問題是局域網通信的問題,也是數據鏈路層的問題。關于IP協議,有兩個協議,IPv4和IPv6,使用較多的是IPv4。IP地址用于標識主機的唯一性。
唐僧取經時,目的是到西天的大雷音寺找如來佛祖,這里如來佛祖就是進程,之前說過了,這里不用管。但是,唐僧來路上問路時,還沒到西天時,就會問“西天怎么走?“,只有到了西天后,才會問"大雷音寺怎么走?“。所以,IP地址=目標網絡+目標主機。我們將主機、路由器統稱為節點。
協議頭格式
網絡協議棧每一層都解決不同的問題。應用層報頭主要解決自身報文完整性、序列與反序列化問題;傳輸層報頭主要支持進行流量控制、擁塞控制、超時重傳、連接管理等。網絡層在通信時要進行路徑選擇和報文的轉發。
IP協議與TCP協議的關系
IP的核心作用:把報文跨網絡轉發到目標主機!到達目標主機的IP層后,就會進行解包,將其交給TCP/UDP了,進而通過端口號交付給上層應用。如果在轉發過程中,這個報文丟包了呢?IP是不關心丟包問題的,因為TCP會處理丟包問題。所以,IP就是提供了一種能力,把數據從A主機,跨網絡,轉發給B主機的能力。但是,有能力就一定能做到嗎?這是不一定的。所以,TCP提供了重發的功能。通過TCP+IP就能有一種可靠的能力,將數據從A主機跨網絡轉發給B主機的能力。這個可靠的能力解決的就是主機距離變長的核心問題。TCP協議用于解決轉發的策略問題,IP協議用于解決具體轉發問題。
IP報頭 = IP標準報頭 + 選項。之前我們在學習套接字時,要將端口號、IP地址轉為網絡序列,就是由TCP報頭和IP報頭決定的。IP報頭中的IP地址是32位的,所以一定不能是點分十進制的。并且接收方能夠得到發送方的信息,也是由TCP報頭和IP報頭決定的。
這里的4位首部長度與TCP是完全相同的,記錄的是IP報頭的長度。16位總長度記錄的是IP報頭+有效載荷的長度。有了這兩個字段后,就可以進行解包了。
- IP是如何解包的?如何封裝的?
因為存在4位首部長度和16位總長度,所以可以進行解包的。封裝與TCP也是一樣的。 - IP是如何分用的?
IP報頭中有8位協議字段,表示的是上層協議的類型。這里面填寫的是TCP/UDP的協議號。TCP是6,UDP是17。
4位版本就是標識是IPv4,還是IPv6。IPv4的IP地址是32位的,最多能標識2^32個IP地址,已經不足了,所以就有了IPv6,IPv6使用128個位標識1個IP地址。但是IPv4和IPv6不兼容。并且要推廣IPv6,不單單只是IPv6更好的問題,而是生態問題,即現在很多內容都使用的是IPv4,要修改這些現有的東西是很困難的。
8位服務類型:3位優先權字段(已經棄用),4位TOS字段,和1位保留字段(必須置為0)。4位TOS分別表示:最小延時,最大吞吐量,最高可靠性,最小成本.這四者相互沖突,只能選擇一個。對于ssh/telnet這樣的應用程序,最小延時比較重要;對于ftp這樣的程序,最大吞吐量比較重要。舉個例子幫助理解,假設唐僧在路過黑風嶺時,人們都告訴他這里很危險,還是繞路走吧,唐僧認為從黑風嶺過只需要1天,而繞路需要7天,所以還是選擇從黑風嶺過,在這里,唐僧在做路徑選擇時,是時間優先的。報文在網絡中傳輸時,有些路徑可能傳輸效率比較高,但是容易丟包;有些則傳輸效率比較低,如可能路徑較長,但是不容易丟包。8位服務類型就是由OS設置報文的轉發策略。
第二行的內容我們后面再介紹。網絡是人搭建的,所以也是可能出現問題的,如可能出現環路問題,報文在一些路由器之間持續來回轉發,這樣就浪費了網絡資源。所以我們要給網絡報文設置一個TTL,這個TTL是一個計數器,每經過一個路由器就讓這個計數器--,當TTL減小到0了,路由器就會將這個報文丟棄。16位首部校驗用于檢測和IP報頭完整性,不用管。
IP報文的分片與組裝
我們上面對于IP報頭的第二行是沒有介紹的。現在我們正式進行講解,要理解第二行,就需要聯合TCP進行理解。
我們知道,TCP協議中存在一個叫做滑動窗口的東西,滑動窗口決定了發送方單次發送的數據總量,大小受擁塞窗口和對方接收緩沖區大小共同決定。為什么不把滑動窗口內的數據打包形成一條報文直接發送呢?而是要弄成多條報文發送呢?
當IP報文太長了,會將IP報文變成小報文,稱為IP報文的分片問題。數據鏈路層規定,單次發送的數據幀的有效載荷長度不能超過MTU(一般是1500字節)。當IP報文太長時,將IP報文交給數據鏈路層就會被告知,此時就需要進行分片了,分片的工作是由網絡層來完成的。對于分片后的報文,未來接收到時是需要進行組裝的,由接收方的網絡層進行組裝。為了能夠完成分片和組裝的工作,IP協議的報頭中就增加了3個字段:16位標識、3位標志、13位片偏移。
分片是好還是不好呢?
1. 其實上層根本就不關心網絡層是否進行了分片、組裝。對于傳輸層而言,發送方發送了1萬字節,只要接收方能夠接收到這1萬字節的數據即可。
2. 假設發送方發送了1萬字節的報文,現在將其分片成了10個報文進行發送,那么在發送的過程中,任何一個報文丟包了,就是不完整的。在傳輸層看來,就是丟包了。我們會發現,進行分片之后,丟包的概率增加了。所以,分片注定不能稱為網絡發送的主流。
如何不分片?
網絡層的作用僅僅只是進行路由,真正決定發送多少數據,什么時候發的是傳輸層。所以,只要傳輸層不發送太長的報文即可不分片。所以,滑動窗口中的數據不是通過一個報文發送,而是分成多個報文發送,是為了減少分片。
UDP沒有滑動窗口,所以UDP很容易造成分片問題,從而導致丟包概率增加。但是既然都使用了UDP,那么說明對于丟包問題并不關心,所以問題并不大。
IP報頭中有一個字段是16位首部校驗和。說明對于組裝,并不會關心有效載荷的組裝是否規范,只會檢查IP報頭的組裝是否規范。并且TCP和UDP的報頭中有校驗和,這里不是首部校驗和,用于檢測整個報文是否完整。
如何進行組裝呢?
IP 分片對傳輸層是透明的,這意味著傳輸層無需關心數據是否被分片以及如何重新組裝。要知道如何進行分片和組裝,需要先知道下面三個問題:
- 接收方如何得知自己收到的報文分片了?
- 接收方如何得知自己收到的分片收全了?
- 接收方如何組裝形成完整的報文?
我們先來看一下IP報頭中第二行的3個字段,了解了這3個字段就可以知道上面3個問題了:
- 16 位標識(id):唯一的標識主機發送的報文。正常來說每一個報文中都應該不同,但是如果IP報文在數據鏈路層被分片了,那么每一個片里面的這個id都是相同的。
- 3 位標志字段:第一位保留(保留的意思是現在不用,但是還沒想好說不定以后要用到)。第二位置為1表示禁止分片,這時候如果報文長度超過 MTU,IP 模塊就會丟棄報文。第三位表示"更多分片",如果分片了的話,最后一個分片置為0,其他是1。類似于一個結束標記。
- 13 位分片偏移:是分片相對于原始 IP 報文開始處的偏移。其實就是在表示當前分片在原報文中處在哪個位置。實際偏移的字節數是這個值除以8得到的。因此,除了最后一個報文之外(之前如果都是8的整數倍,最后一片的偏移量也一定是8的整數倍),其他報文的長度必須是8的整數倍(否則報文就不連續了)。
接收方如何得知自己收到的報文分片了?
我們來看看接收到的報文分片與沒分片時,3個字段的數值:
- 沒有分片,一個完整報文:16位標識,000,0
- 第一個分片? ? ? ? ? ? ? ? ? ? ?:16位標識,001,0
- 中間分片? ? ? ? ? ? ? ? ? ? ? ? ?:16位標識,001,!0
- 結尾分片? ? ? ? ? ? ? ? ? ? ? ? ?:16位標識,000,!0
所以,只要3位標志或13位分片便宜有一個不為0,這個報文就分片了。
接收方如何得知自己收到的分片收全了?
首先,根據16位標識,可以將所有分片放在一起,然后按照片偏移進行升序排序。將所有的分片收集到之后,可能會存在一些分片丟包了:
- 第一個分片丟包,排序完成之后第一片的片偏移不是0
- 結尾分片丟包,因為所有分片中只有結尾分片的3位標志字段是0,所以是可以知道的
- 中間分片丟包,下一個分片的偏移量 = 當前分片偏移量 + 當前分片長度,所以可以通過計算得知是否有中間分片丟包
當上面3種情況都沒有出現時,就說明所有分片都收全了。
接收方如何組裝形成完整的報文?
只需要保證接收到所有的分片,并排序之后,將其進行組裝即可。
如果要分片,應該如何分片呢?
注意:分片指的是對IP報文的有效載荷進行分片。所以,所謂片偏移是數據相對于原始IP報文有效載荷的起始的偏移量。總長度是16位的,而片偏移只有13位。所以,片偏移具體的數字,必須是8的整數倍。當數據的偏移量是1480時,報頭中的片偏移存的是1480/8=185。分片之后,每一片就是一個IP報文,所以每一個分片都要含有IP報頭。
假設我們現在有一個IP報文,長度是3020字節,其中IP報頭是20字節,有效載荷是3000字節。因為3020大于1500,所以是需要進行分片的。分片分的是有效載荷,所以對于報頭不用管。
分片后的3個報文的IP報頭拷貝自原先的IP報頭,第二行的數據會進行修改。分片時最后剩下的一個報文長度不是8的整數倍時,可以進行填充,未來再根據IP報頭的總長度將填充的去掉即可。
注意:分片、組裝不一定只能在發送方和接收方進行,因為中途經過的一些路由器的MTU可能不是1500。因為有片偏移的存在,所以即使是二次分片了,也是可以組裝的。但是這種情況出現的概率是非常低的。
網段劃分
網段劃分也叫子網劃分。
網段劃分是什么?為什么要進行網段劃分?
唐僧在從東土大唐去往西天的過程中,西天是目標地址,但是如果沒有從東土大唐到西天的路的話,是不能前往西天的。也就是說,有了目標地址,但是沒路的話是無法到達目標地址的。所以,報文在網絡中傳輸,光有目標IP地址是不夠的。而路是被設計過的,所以網絡也是被設計過的,也就是說,在報文轉發過程中,會經歷一個一個的子網,這些子網是被設計過的,使報文能從主機B到達主機C。設計網絡的一個設計方案就是子網劃分。所以,子網劃分就是對網絡進行人為的設置,使得未來可以通過物理網絡和子網劃分將報文發送到目標主機。當然,子網劃分是硬件層面的,在轉發過程中,還會配合軟件層面的路由算法,通過軟件+硬件,就可以將網絡設施建設好了。這些網絡設施是被誰設計的呢?是三大運營商設計的。
我們會發現,上面的子網內主機的IP地址都以192.168.128開頭,下面的子網內主機的IP地址都以192.168.144開頭。192.168.128.0叫做上面子網的網絡號,192.168.144.0叫做下面子網的網絡號。在一個子網內的所有主機的網絡號是完全一樣的,但主機號一定不一樣。所以,IP地址=網絡地址+主機地址。這樣就能在一個子網內標識一個主機的唯一性。路由器負責的就是將報文從一個子網轉發到另一個子網,所以路由器一定要有兩個IP地址。
1.子網內的主機的IP地址是從哪里來的?
在一個子網中,路由器是第一個入網的設備。路由器具有構建子網的能力,也就是說,子網內的主機的IP地址是從路由器來的。當一個設備要上網時,就要先連接路由器,連接路由器就是向路由器申請一個IP地址。
2.路由器的IP地址是怎么來的?
路由器的網絡標識一般都是固定的,而主機標識永遠都是1。當一臺主機連接了一個子網,獲取到了一個IP地址后,是可以知道這個IP地址哪一部分是網絡地址,那一部分是主機地址的。假設現在主機192.168.128.11要發送報文給192.168.144.10。主機192.168.128.11就會分析目標IP地址的網絡地址部分與自己的網絡地址進行比較,若相同,則就是局域網通信,發現不同,說明目標主機不在自己所在的子網內,但是它也不知道這個目標主機在哪里,此時只能將這個報文交給路由器。所以當子網被劃分了,就自然有了轉發算法。
- 有一種技術叫做DHCP,能夠自動的給子網內新增主機節點分配IP 地址,避免了手動管理IP 的不便;
- 一般的路由器都帶有DHCP功能。因此路由器也可以看做一個DHCP服務器。
根據一個IP地址進行報文轉發,有兩個階段:
- 根據目標網絡,轉發報文到目標網絡
- 轉發到目標網絡后,把報文進行內網轉發
我們舉一個例子幫助理解上面的過程。在大學中,會有非常非常多的學院,而每一個學院內的學生都會有學號,我們可以簡單地將學號定義為學號 = 院號 + 編號。假設現在有計算機學院(01)、理學院(02)、文學院(03)、外國語學院(04)、化環學院(05)、醫學院(06),對于每一個院,都會有自己的院群。假設現在計算機學院中有一名學生張三,學號是01023,醫學院有一名學生李四,學號06077。校方為了方便管理每一個學院,所以會給每一個學院安排一個院學生會主席,這個主席本質上也是學生,所以他也要有學號,假設計算機學院的主席學號是01110,醫學院的學生會主席學號是06120,并且這些學生會主席會統一拉入一個校群,以方便相互交流,也就是說,院學生會主席既在自己的院群,又在校群。現在,計算機學院的張三撿到了一個錢包,這個錢包當中有一個學生證,但是已經被損壞的有一些嚴重了,只能看清楚里面的學號,這個學號是06077。張三雖然不知道這個學號對應的學生是誰,但是他知道這個學生不是和自己一個學院的,在自己這個學院當中,知道這個學號屬于哪一個學院的人,一定是院學生會主席。所以,張三會將這個學號06077和自己的電話發送到群聊當中,并@學生會主席,告訴學生會主席自己撿到一個錢包,并且失主一定不是我們院的。院學生會主席可能知道06是那個院,也可能不知道,但這并不重要,因為他在校群當中。計算機學院的學生會主席就會將這條消息轉發到校群中,如果他知道06是醫學院,他就會@醫學院的學生會主席。無論是否@,這條消息最終都會被醫學院的學生會主席拿到,醫學院的學生會主席就會將這條消息轉發到醫學院的院群當中。他知道06077是誰就直接@他,不知道也無所謂,這樣,06077的這位同學就能夠看到這條消息了,消息內有張三的電話,李四就能聯系上張三,從而拿回自己的錢包了。
在這個過程中,每一個學院就是一個內/子/局域網,院學生會主席就是路由器,校群是一個極簡版的公網,張三發到院群中的數據就是目標IP+有效載荷。這條報文從內網轉發到公網,再從公網轉發到內網,即可發送到目標IP。張三能夠這么高效地將消息發送給李四,是因為學校的結構是被精心設計過的。將不同的學生劃分到不同的學院當中,就是子網劃分的過程。
為什么要進行子網劃分?因為子網劃分后報文的傳輸效率變高了。為什么傳輸效率會變高呢?
在學校中,如果沒有根據學院來劃分學生,只是給每一個學生一個編號,那么要找到一個學生只能線性遍歷。因為將錢包歸還給別人本質上是一種查找,查找的本質是淘汰,所以當醫學院的學生會主席拿到張三發出的消息,本質上是淘汰了計算機學院、理學院、文學院、外國語學院、化環學院。線性遍歷時,一次淘汰1個人,而子網劃分一次可以淘汰很多人。所以,子網劃分之所以效率高,是因為淘汰的效率高了,進而導致查找效率高了。所以,之所以要進行子網劃分,我因為支持網絡建設,提高淘汰的效率。
在進入目標子網之前,張三、計算機學院的院學生會主席是不關心06077中的077這個數字的,只關心06。報文在進行轉發的過程中,在到達目標網絡之前,路由只看IP中的目標網絡部分!!到達目標網絡之后,才關心077,根據077做內網轉發。IP=目標網絡+目標主機,當我們進行路上路由的時候,只關心目標網絡!!路由的基本單位是網絡!!
怎么進行網段劃分?
網段劃分的具體做法
過去曾經提出一種劃分網絡號和主機號的方案,把所有IP地址分為五類。全球范圍內,允許存在2^7個A類網絡,每一個A類網絡中允許存在的主機數是2~24個。申請網絡時,并不是以國家為單位申請的。而是以公司、組織等為單位申請的,申請到網絡之后,就可以對網絡進行建設了。這種劃分方案是有問題的。像A類、B類網絡,本身是很多的,容易造成IP地址浪費的問題。針對這種情況提出了新的劃分方案,稱為CIDR。引入一個額外的子網掩碼來區分網絡號和主機號,子網掩碼也是一個32位的正整數.通常用一串"0"來結尾,將IP地址和子網掩碼進行"按位與"操作,得到的結果就是網絡號,網絡號和主機號的劃分與這個IP地址是A類、B類還是C類無關。有了子網掩碼后,就可以動態調整網絡號和主機號的位數。
我們來看兩個劃分子網的例子:
雖然這里子網地址范圍內有256個IP地址,但是實際上末尾全0或全1是無法使用的,稱為特殊IP。末尾全0時,即140.252.20.0是網絡號,末尾全1時,即140.252.20.255是廣播地址。所以真正只有254個。
68的二進制是01000100,240的二進制是11110000,按位與的結果是01000000,所以按位與完就是140.252.20.64,這是網絡號。子網掩碼的最后是240,是11110000,說明前28位是網絡號,后4位是主機號。主機號就是從0000-1111,所以就是140.252.20.64-140.252.20.79。有15個,但是實際上只有13個可以使用。
一個路由器會有2個子網掩碼,分別與兩個IP地址對應。
特殊的IP地址
將IP地址中的主機地址全部設為0,就成為了網絡號,代表這個局域網;將IP地址中的主機地址全部設為1,就成為了廣播地址,用于給同一個鏈路中相互連接的所有主機發送數據包;127.*的IP地址用于本機環回,通常是127.0.0.1。
當目標IP地址是127*時,并不會走網絡,而是走網絡協議棧到IP層,然后判斷,若發現是本主機,就將報文放到IP協議的輸入隊列中,然后就可以被本主機讀取了不會到達鏈路層及下面的區域。
IP地址的數量限制
IP地址是一個32位的整數,所以總共會有2^32個IP地址,大約是43億。并且由于一些特殊IP的存在,數量遠不及43億。CIDR在一定程度上緩解了IP地址不足的問題,但仍然是不夠用的,有3種方法解決這個問題:
- 路由器動態分配IP地址:只給接入網絡的設備分配IP地址.因此同一個MAC地址的設備,每次接入互聯網中,得到的IP地址不一定是相同的;這是增加IP地址利用率的做法,它不能解決IP地址資源不足的問題;
- NAT技術,解決IP地址資源不足的問題的技術,后面說;
- 升級為IPv6。
私有IP地址和公網IP地址
可以將網絡分為局域網和公網。在局域網內使用的IP地址稱為私有IP地址。只能使用私有IP地址來組建局域網,不能出現在公網中。也就是說,在所有的IP地址中,切分出來一部分IP地址只能用于搭建局域網,這部分IP地址就稱為私有IP。其余的稱為公網IP。
如果一個組織內部組建局域網,IP地址只用于局域網內的通信,而不直接連到Internet上,理論上使用任意的IP地址都可以,但是RFC1918規定了用于組建局域網的私有IP地址:
- 10.*,前8位是網絡號,共16,777,216個地址
- 172.16.*到172.31.*,前12位是網絡號,共1,048,576個地址
- 192.168.*,前16位是網絡號,共65,536個地址
私有IP只在內網進行使用,所以不同的子網中,是可以出現相同的私有IP的,公網IP是不能重復的。可以使用ifconfig查看當前主機的IP地址和子網掩碼:
上面3種私有IP地址種,從下往上的主機數是越來越多的,所以做家庭組網一般都是192.168,而在學校等場所可能使用的就是172.16,在大型組織或企業中,可能使用的就是10。所以,不同的組織根據自身規模的大小,會選擇不同的私有IP來搭建自己的私有網絡。網絡建設的時候,在內網,在公網,統一采用各自的子網掩碼的方式,進行網絡建設!!
當我們在家庭中想構建子網,只需要買一個路由器即可,因為路由器具有構建子網的能力。路由器為什么有構建子網的能力?因為路由器可以給接入的主機分配私有IP地址,而私有IP可以直接被使用。構建子網/局域網,不僅僅我們在做,運營商也在做也就是說,從我們的路由器出去的報文不一定直接就到公網了,可能是先到另一個子網。
運營商
基本的網絡情況
無論是申請公網IP,還是網絡建設,都是運營商來做的。我們來看看具體的步驟。
假設在家里想上網,就可以找運營商,運營商就會上門將網口弄好,將網線拉到家里,然后配備上路由器,然后設置好賬號和密碼,通過賬號和密碼就可以連接上家里的路由器了,因為路由器具有構建子網的能力,此時就構建好了家里的子網了。家里的IP地址通常是192.168開頭的。
家里的路由器是不會直接連接廣域網的,而是連接運營商的路由器,這個路由器構建的子網采用更大的私有IP,如172.16開頭或10開頭的,通常一個鎮/區/市等有一個專門的路由器構建。這個子網屬于運營商構建的,家里的路由器未來就會將報文轉發到運營商構建的子網當中。所以,家里的路由器是橫跨兩個子網的,一個是家里的子網,由家里的路由器構建,一個是運營商構建的子網,由運營商的路由器構建。路由器分為家用路由器和企業路由器。企業路由器能夠構建出更大的子網。
既然家用路由器會集連兩個網絡,那么它就需要配備有兩個IP地址。圖中192.168.1.1稱為子網IP,也稱為LAN口IP,10.1.1.2稱為WAN口IP。當家里的路由器插上網線之后,不是立即構建自己的子網,而是先向運營商的路由器申請一個IP地址。所以,從家里路由器出去的報文,并沒有到達公網,而是必須先到達運營商構建的一個更大的子網中。家里主機的報文一定能夠交給家里的路由器,到達家里路由器的報文也一定能夠交給運營商的路由器。
1. 我們在訪問各個網頁,使用各個應用時,都是需要網絡的,為什么不是將錢交給這些網頁或應用的開發者,而是將錢交給運營商呢?運營商在配置我們家里的路由器時,是會有賬號的,這個賬號通常就是手機號,未來沒錢了,直接向這個手機號充錢即可。也就是說,路由器在配置時,會有兩套賬號體系,第一套體系是讓運營商識別我們的家用路由器的,當家用路由器連接上運營商的路由器時,就會將賬號,也就是手機號推送到運營商的路由器,運營商的路由器就會判斷這個手機號是否有話費,若有話費,就允許將這個路由器發送過來的報文轉發到公網上,沒有則不轉發;另一套賬號體系是家用路由器構建的子網的名稱和密碼,供人們進行連接的。所以,我們的報文未來必須經過運營商的路由器做轉發,才能到達公網!所以交錢需要交給運營商。
2. 運營商可以因為你欠費不讓你如公網,也可以因為你訪問的目標IP地址非法而攔截你。當我們要訪問谷歌官網時,運營商就會識別出這個域名對應的IP地址是海外IP,是不合法的,就攔截。所以科技上網的本質就是騙過運營商,讓運營商識別不出來這個IP地址。
假設我們今天要訪問抖音的服務器,抖音的服務器肯定配備了公網IP,比如說是122.77.241.3,而當前主機的IP地址是192.168.1.201。每個主機都會有自己的路由表,其中就有自己的IP地址和子網掩碼,將自己的IP地址和子網掩碼進行按位與就可以獲取到自己的網絡號,再將目標主機的IP地址與自己的子網掩碼進行按位與即可得到目標主機的網絡號。所以它是可以判斷出122.77.241.3這個IP地址對應的網絡號不是自己當前的網絡的。當發現不是,這臺主機就會將這個報文發送給當前子網內的路由器,發送到路由器之后,路由器就會將122.77.241.3與自己的子網掩碼進行按位與,發現不是運營商路由器構建的子網,就會將這條報文推送給運營商的路由器。上面的圖只是一個簡化的圖,實際上運營商的出口路由器可能會有很多層狀結構,從而搭建出一個非常復雜的子網結構,但是不需要管,因為這并不影響報文通過運營商的出口路由器發送到公網當中。當報文被轉發到公網之后,就可以轉發到目標主機了,具體細節后面說。抖音的服務器肯定也是在某一個內網當中,這個內網的入口路由器就會判斷發送過來的報文是否是當前內網的,發現是,就做內網轉發即可。
抖音的服務器接收到請求之后,就需要發送回一個應答,怎么發送應答呢? 如果應答的報文中的目標IP地址填入一個192.168.1.201,此時是無法轉回來的,因為這是一個私有IP。所以,發送報文時真正的步驟是這樣的。從主機發送出去時,源IP地址是192.169.1.201,目標IP地址是122.77.241.3,當報文每轉發到1個路由器,就回將這條報文的源IP地址修改成這個路由器的WAN口IP,因為私有IP是不能出現在公網或另一個子網當中的,先修改為10.1.1.2,再修改為122.77.241.4,然后就可以通過公網進行轉發了。抖音服務器的應答報文中,源IP地址是122.77.241.3,目標IP地址是122.77.241.4。此時通過公網,就可以將這個應答報文發送給之前發送的出入口路由器處。我們將內網到公網做源IP地址替換的技術稱為NAT技術。具體如何將報文從運營商的出入口路由器轉到發送報文的主機上,后面再說。為什么NAT技術能緩解IP地址不足的問題?因為它單獨切分了一部分IP,只用它來做內網,這樣IP地址可以被重復利用了!!!
全球網絡
公網本質上是對全球的公網IP進行劃分的過程。公網IP是以國家,組織,公司,學校等為單位,進行申請的。我們這里就以國家為例。假設美國申請的IP地址是1.0.0.0/8,俄羅斯是2.0.0.0/8,韓國是3.0.0.0/8,日本是4.0.0.0/8,法國是5.0.0.0/8,中國是6.0.0.0/8,英國是7.0.0.0/8,這里/8的意思是IP地址的前8位表示網絡號。每個國家都會有一個國家級別的國際路由器。當然,每一個國家都會有多個IP地址,且有多個國際路由器,這里簡便一點,就看1個。這些國際路由器會在同一個網絡當中。
因為這些路由器都是位于同一個子網的,所以,未來每個國家都可以將自己的網絡號、子網掩碼等通過網絡告訴其他國家,所以每一個國家的國際路由器中都可以維護一個路由器表目,我們以美國的路由器為例:
目標網絡 | 子網掩碼 | 地區 | 下一跳 |
1.0.0.0 | 255.0.0.0 | 美國 | |
2.0.0.0 | 255.0.0.0 | 俄羅斯 | |
... | |||
6.0.0.0 | 255.0.0.0 | 中國 | 6.0.0.1 |
... |
中國劃分到的網段就是6.0.0.1/8,所以網段劃分的直接體現就是把IP地址的若干位充當子網的入口,將配置信息體現在路由器當中。全球都以這種做法來做,就可以在全球范圍內進行網段劃分。中國拿到的是6.0.0.1/8,剩下的24個比特位就可以由中國自由支配了。
現在中國的IP地址就是6開頭的,然后要怎么再劃分呢?因為前8個比特位已經劃分過了,所以我們使用接下來的8個比特位進行劃分省份,我們這里只列舉幾個省份。每個省也會有一個省級的路由器。將中國內部的所有省的省路由器和中國的國際路由器放到同一個網絡當中。當一個省成功接入網絡,就會將自己的省路由器的網絡號和子網掩碼發送給這個子網當中的所有路由器。同樣可以維護一個路由器表目,與上面是一樣的。這里是可以繼續對公網劃分的,比如說再進一步劃分到市,但是道理是一樣的,這里就到省即可。
此時國內每一個省的運營商就可以組件省內的局域網了。當然也可以在省內進行市級別的公網IP劃分,其實就是擴展子網掩碼。但是這里就不做了。每一臺路由器都會有一個缺省路由器,當路由器拿到一個不認識的IP地址時,就會將報文交給缺省路由器,家里主機的缺省路由器是家里的路由器,家里路由器的缺省路由器就是運營商的路由器,省級路由器的缺省路由器是國家級路由器。
這里的Destination和默認網關就是缺省路由器的IP地址。
這里需要說明一下,在NAT中,并不是每經過一個路由器就會變換一下源IP地址,而是每經過一個內網才會變換,假如從廣東省的一臺主機給美國發消息,那么這個消息到美國時,源IP地址是6.2.0.1/16,而不是6.0.0.1/8。當美國內部的主機接收到消息后,會進行應答,報文到達美國的國家級路由器時,就會將6.2.0.1與這個路由器的子網掩碼進行按位與,得到6.0.0.0,然后查看這個路由器的路由表目,得到下一跳是6.0.0.1,就可以通過公網發送到中國了。
所以,現在我們已經知道了一個報文從內網 -> 公網 -> 內網的過程了,當然,傳輸時也不一定每次都會到公網。至于到了目標主機的內網后,怎么將報文轉給目標主機,后面說。
路由
當網絡的設施建設好了,其實大部分路由問題就已經解決了。路由器一般要盡可能地幫助我們進行路由,所以路由器要配置默認路由,也叫缺省路由。也就是說,當報文到達了某一個路由器,進行路由時,路由器一定不能說不知道,而是一定要告訴報文下一個目的地是哪里。注意:不僅僅是路由器有缺省路由,主機也有缺省路由。
當報文到達某一個路由器進行路由時,無非就是3種情況。當路由器不知道IP地址是誰時,直接將報文交給缺省路由器;當路由器知道IP地址是誰時,直接將報文交給指定的路由器;當前這個路由器就是報文的目標IP地址是入口路由器。在這個過程中,都是根據目的網絡進行路由的。當到達了目標IP的入口路由器時,就需要進行內網轉發了。
我們現在已經知道了路由的一個宏觀過程,那么在報文到達每一個路由器時,是怎么進行路由的呢?所以,主機和路由器在網絡層都配備了自己的路由表!可以通過route查看路由表。
Destination是網絡號,Genmask表示的是子網掩碼,Iface是網絡接口,Flags帶U時,表示這個條目是有效的,Gateway是下一跳IP地址。當一個報文到達了一個路由器時,路由器就會拿著報文中的目標IP與自己路由表中的子網一個一個按位與,查看按位與后的結果是否與這個子網掩碼對應的網絡號相同。如果相同,直接通過Iface的網絡接口轉發到指定的網絡;若都不相同,就通過default的Iface進行轉發,default就是缺省路由。
上面的圖是云服務器的路由表,畢竟不是真的路由器,所以并不是很詳細,我們來看一張真實的路由器的路由表:
我們會發現,為什么在進行內網轉發時,下一跳的IP地址是*呢?這是因為在進行內網轉發時,是數據鏈路層的工作,更加關注的是MAC地址。后面說。
路由表生成算法
一個路由器是怎么知道他的缺省路由是誰?一個路由器是怎么知道他所在的子網當中其他路由器的信息的?路由表可以由網絡管理員手動維護(靜態路由),也可以通過一些算法自動生成(動態路
由)。我們可以直接將其理解成路由器上線之后,可以向他所在的子網廣播自己的網絡信息,然后他再記錄下與自己直連的網絡即可。