Linux 網絡基礎(三) TCP/IP協議


一、TCP 與 IP 的關系

IP 層的核心作用是定位主機,具有將數據從主機 A 發送到主機 B 的能力,但是能力并不能保證一定能夠做到,所以這時就需要 TCP 起作用了,TCP 可以通過超時重傳、擁塞控制等策略來保證數據能夠發送到 B 主機。
所以,TCP 提供的是策略(保證可靠),而 IP 付出的是行動。


二、IP 協議的基本概念

2b2477bd46504263baa9646622a9b2b3.png

網絡層要解決的問題是:將數據從一臺主機送到另一臺主機,也就是數據的路由

  • 主機:配有?IP?地址,但是不進行路由控制的設備。
  • 路由器:即配有?IP?地址,又能進行路由控制。
  • 節點:主機和路由器的統稱。

在路徑選擇中,目的 IP 非常重要,決定了路徑該如何走。
數據進行的網絡傳輸一般都是跨網絡的,而路由器就是連接多個網絡的硬件設備,因此數據在進行跨網絡傳輸時一定需要經過多個路由器。
ip = 目標網絡 + 目標主機

舉個例子,我們要到北京故宮,北京就像目標網絡,故宮就像目標主機,所以我們要先找到目標網絡再找到目標主機。
IP 地址是進行路由的根本。


三、IP 協議格式

  • 4 位版本號(version):指定 IP 協議的版本(IPv4/IPv6),對于 IPv4 來說,就是 4。
  • 4 位頭部長度(header length):表示 IP 報頭的長度,以 4 字節為單位。IP 頭部的長度是多少個 32 bit,也就是 length * 4 的字節數。4bit 表示最大的數字是 15,因此 IP 頭部最大長度是 60 字節。
  • 8 位服務類型(Type Of Service):找到最優路徑。3 位優先權字段(已經棄用),4 位 TOS 字段,和 1 位保留字段(必須置為0)。
  • 4位 TOS 分別表示:最小延時,最大吞吐量,最高可靠性,最小成本。這四者相互沖突只能選擇一個,對于 ssh/telnet 這樣的應用程序,最小延時比較重要。對于 ftp 這樣的程序,最大吞吐量比較重要。
  • 16 位總長度(total length):IP 報文(IP 報頭 + 有效載荷)的總長度,IP 數據報整體占多少個字節,用于將各個IP報文進行分離。
  • 16 位標識(id):唯一的標識主機發送的報文。如果 IP 報文在數據鏈路層被分片了,那么每一個片里面的這個 id 都是相同的。?
  • 3 位標志字段:第一位保留(保留的意思是暫時沒有規定該字段的意義)。第二位置為 1 表示禁止分片,這時候如果報文長度超過 MTU,IP 模塊就會丟棄報文。第三位表示 “更多分片”,如果報文沒有進行分片,則該字段設置為 0,如果報文進行了分片,則除了最后一個分片報文設置為 0 以外,其余分片報文均設置為 1,類似于一個結束標記。
  • 13 位分片偏移(framegament offset):分片相對于原始 IP 報文開始處的偏移,表示當前分片在原數據中的偏移位置,實際偏移的字節數是這個值 *8 得到的。因此, 除了最后一個報文之外,其他報文的長度必須是 8 的整數倍,否則報文就不連續了。
  • 8 位生存時間(Time To Live,TTL):數據報到達目的地的最大報文跳數,一般是 64。每次經過一個路由,TTL?-= 1,一直減到 0 還沒到達,那么就丟棄了。這個字段主要是用來防止出現路由循環。
  • 8 位協議:表示上層協議的類型。
  • 16 位頭部校驗和:使用 CRC 進行校驗,來鑒別數據報的首部是否損壞,但不檢驗數據部分。
  • 32 位源地址和 32 位目標地址:表示發送端和接收端所對應的 IP 地址。
  • 選項字段:不定長,最多 40 字節。

1、IP 將報頭與有效載荷進行分離(解包)& 向上交付(分用)

如何將報頭與有效載荷分離?

首先要知道報文部分把選項除去一共是 20 字節(跟 TCP 一樣)
IP 報頭中有一個是?4 位首部長度,基本單位是四字節。
所以大小范圍是【0~60】字節。根據計算,如果沒有選項,那么就填寫 0101(5 的二進制)。

既然報頭和選項都能讀取到了,總長度也知道了(16 位總長度),那么剩下的就是有效載荷了。

有效載荷 = 16位總長度 - 4位首部長度*4


向上交付給哪個協議?

在 IP 報頭當中有一個字段叫做 8 位協議,該字段表示的就是上層協議的類型,IP 就是根據該字段判定應該將分離出來的有效載荷交付給上層的哪一個協議(TCP/UDP)的。

該字段是發送方的 IP 層從上層傳輸層獲取到數據后填充的,比如是上層 TCP 交給 IP 層的數據,那么該數據在封裝 IP 報頭時的 8 位協議填充的就是 TCP 對應的編號。


2、8 位生存時間

報文在網絡傳輸過程中,可能因為某些原因導致報文無法到達目標主機,比如報文在路由時出現了環路路由的情況,或者目標主機已經異常離線了,此時這個報文就成了一個廢棄的游離報文。

為了避免網絡當中出現大量的游離報文,于是在IP的報頭當中就出現了一個字段,叫做 8 位生存時間)。8 位生存時間代表的是報文到達目的地的最大報文跳數,每當報文經過一次路由,這里的生存時間就會減一,當生存時間減為 0 時該報文就會被自動丟棄,此時這個報文就會在網絡中消散。


3、32 位源 IP 地址和 32 位目的 IP 地址

數據想要發送到對端主機,要在路由器之間一跳一跳的過去,而路由器的轉發就需要源 IP 和目的 IP。
當接收端收到了發送端發來的數據后,接收端可能也想要給發送端發送數據,因此發送端在發送數據時除了需要指明該數據的目的 IP 地址,還需要指明該數據的源 IP 地址,也就是發送端的 IP 地址。即便接收端收到數據后沒有數據想要發送給發送端,但至少接收端需要向發送端發送一個響應報文,表明發送端發送的數據已經被接收端可靠的收到了,因此發送出去的數據除了需要指明該數據的目的 IP 地址,還需要指明該數據的源 IP 地址。


(1)綁定 socket

端口號的綁定其實是 TCP/UDP 層用來進行從操作系統向進程交付數據。
IP 地址就是綁定在 IP 層,用于數據在網絡傳輸過程中的路由轉發。

發送數據時,不需要指明發送數據的源 IP 地址和源端口號,因為傳輸層和網絡層都是在操作系統內核當中實現的,數據在進行封裝時操作系統會自行填充上對應的源 IP 地址和源端口號。


四、網段劃分(重要)

1、子網劃分的原因

用一個場景舉例幫助理解:我們的入學學號不是隨便給的,它包含了我們的入學年份、學院、班級等信息,假設學號只包含學院號 + 自己的編號。那么我們就可以通過學號知道你是哪個學院的,你是誰。
假設每個學院都有一個負責人,他也有一個自己的學號,每個學院的負責人都在一個大群里。現在張三的學生證丟了, 當張三的學生證被李四撿到了后,李四發現張三不是自己學院的人,但不知道張三到底是哪個學院的,那么李四就只能將這個學生證給學院的負責人:王五。因為王五清楚每一個學院的編號,所以他就可以將學生證交給對應學院的負責人:趙六,然后趙六就可以把學生證歸還給張三。

我們將張三和李四叫做源主機目標主機,負責人們就是路由器,院里的群我們叫做局域網,把負責人的群叫做公網

每個同學都以一個學號(IP 地址),而且每個同學都得歸類到每個學院。
類比到計算機中:互聯網中的每一個主機都隸屬于一個子網, 以方便定位到具體主機,提高查找效率。


2、IP 地址的劃分

IP?地址分為兩個部分:網絡號(表征的是不同的區域)和主機號

  • 網絡號:保證相互連接的兩個網段具有不同的標識。在不同的查找過程中,不斷變大且是收斂的。
  • 主機號:同一網段內,主機之間具有相同的網絡號,但是必須有不同的主機號。

路由器連接了兩個網段,一般主機標識都是 1。對于網絡標識來說,同一網段內主機的網絡標識是相同的,不同網段內主機的網絡標識是不同的。而對于主機標識而言,同一網段內主機的主機標識是不同的,不同網段內主機的主機標識是可以相同的。

  • 不同的子網其實就是把網絡號相同的主機放到一起。
  • 如果在子網中新增一臺主機,則這臺主機的網絡號和這個子網的網絡號一致,但是主機號必須不能和子網中的其他主機重復。

通過合理設置主機號和網絡號就可以保證在相互連接的網絡中,每臺主機的 IP 地址都不相同。

可以看到一個子網內有很多主機,這些主機是由路由器管理的。實際上手動管理 IP 地址是一件非常麻煩的事情,當子網中新增主機時需要給其分配一個 IP 地址,當子網當中有主機斷開網絡時又需要將其 IP 地址進行回收,便于分配給后續新增的主機使用。


(1)DHCP 技術

對于 IP 地址的分配和回收,一般不會選擇手動進行,而是采用 DHCP 技術。

DHCP 通常被應用在大型的局域網環境中,其主要作用就是集中地址管理、分配 IP 地址,使網絡環境中的主機動態獲得 IP 地址、Gateway 地址、DNS 服務器地址等信息,避免了手動管理 IP 的不便,并能夠提升地址的使用率。
DHCP 是一個基于 UDP 的應用層協議,一般的路由器都帶有 DHCP 功能,因此路由器也可以看作一個 DHCP 服務器。

當我們連接 WiFi 時,本質就是路由器就會給你動態分配了一個 IP 地址,然后就可以基于這個 IP 地址進行各種上網動作了。


3、分類劃分法

過去曾經提出一種劃分網絡號和主機號的方案,把所有 IP 地址分為五類,如下圖所示:

當要判斷一個 IP 地址是屬于哪一類時,只需要遍歷 IP 地址的前 5 個比特位,第幾個比特位最先出現 0 值,那么這個 IP 地址對應就屬于 A、B、C、D、E 類地址。

這里就是把 IP 地址看成一個大蛋糕,按照 ABCDE 分成若干塊,要多少 A 類或者 B 類自己去申請即可,這種劃分方法就叫做分類劃分法

隨著?Internet?的飛速發展,這種劃分方案的局限性很快顯現出來,大多數組織都申請?B?類網絡地址,導致?B?類地址很快就分配完了,而?A?類卻浪費了大量地址。

例如,申請了一個?B?類地址,理論上一個子網內能允許 65536?個主機,A?類地址的子網內的主機數更多。然而實際網絡架設中,不會存在一個子網內有這么多的情況,因此大量的?IP?地址都被浪費掉了。


(1)CIDR

針對上面這種情況,在分類劃分法的基礎上出現了一種新的劃分方案,稱為 CIDR(Classless Interdomain Routing):

  • 引入一個額外的子網掩碼(subnet mask)來區分網絡號和主機號。
  • 子網掩碼也是一個 32 位的正整數,通常用一串 "0" 來結尾。
  • 將 IP 地址和子網掩碼進行 “按位與”?操作,得到的結果就是網絡號
  • 網絡號和主機號的劃分與這個 IP 地址是 A 類、B 類還是 C 類無關。

可以給不同的路由器配置不同位數的子網掩碼,這樣就能看到不同的網絡號了。

目的 IP & 當前路由器的子網掩碼 = 該報文要去的目的網絡

因為不同的路由器一定至少要級聯 2 個網絡,每一個網絡的網絡號可能是不同的。每個路由器都要給自己直接鏈接的網絡配置對應的子網掩碼。

目標網絡和子網掩碼是路由器內置好的。

此時一個網絡就被更細粒度的劃分成了一個個更小的子網,通過不斷的子網劃分,子網中 IP 地址對應的主機號就越來越短,因此子網當中可用 IP 地址的個數也就越來越少,這也就避免了 IP 地址被大量浪費的情況。

可見,IP?地址與子網掩碼做與運算可以得到網絡號,主機號從全?0?到全?1?就是子網的地址范圍。

IP?地址和子網掩碼還有一種更簡潔的表示方法,例如?140.252.20.68/24,表示?IP?地址為?140.252.20.68,子網掩碼的高 24 位是?1,也就是?255.255.255.0。

舉例:在某一子網中將 IP 地址的前 24 位作為網絡號,那么該網絡對應的子網掩碼的 32 個比特位中的前 24 位就為 1,剩下的 8 個比特位為 0,將其用點分十機制表示就是 255.255.255.0。
假設該子網當中有一臺主機對應的 IP 地址是 140.252.20.68,那么將這個 IP 地址與該網絡對應的子網掩碼進行 “按位與” 操作后得到的就是 140.252.20.0,這就是這個子網對應的網絡號。
實際在用子網掩碼與子網當中主機的 IP 地址進行 “按位與” 操作時,本質就是保留了主機 IP 地址中前 24 個比特位的原貌,將剩下的 8 個比特位的值清 0 了而已,也就是將主機號清 0 了,那么子網地址范圍就為:【140.252.20.0 ~ 140.252.20.255】


4、特殊的 IP 地址

不是所有的 IP 都會在公網中使用,有些 IP 地址是有特殊的作用的:

  • IP 地址中的主機地址全部設為 0,就成為了網絡號,代表這個局域網。
  • IP 地址中的主機地址全部設為 1,就成為了廣播地址,用于給同一個鏈路中相互連接的所有主機發送數據包。
  • 127.* 的 IP 地址用于本機環回測試,通常是 127.0.0.1。


5、IP?地址的數量限制

IP?地址(IPv4)是一個?4?字節?32?位的正整數。那么一共只有 2^32?個?IP?地址,大概是?43?億左右。

TCP/IP 協議規定,每個主機都需要有一個?IP?地址,這是否意味著一共只有?43?億臺主機能接入網絡嗎?
實際上, 由于一些特殊的? IP? 地址的存在, 數量遠不足? 43? 億。 另外? IP? 地址并非是按照主機臺數來配置的, 而是每一個網卡都需要配置一個或多個 IP? 地址。

CIDR?只是提高了利用率,在一定程度上緩解了?IP?地址不夠用的問題(提高了利用率,減少了浪費,但是?IP?地址的絕對上限并沒有增加),仍然不是很夠用。


(1)解決 IP 地址不足問題

有三種方式:

  1. 動態分配 IP 地址:只給接入網絡的設備分配 IP 地址。因此同一個 MAC 地址的設備,每次接入互聯網中,得到的 IP 地址不一定是相同的。
  2. NAT 技術:能夠讓不同局域網當中同時存在兩個相同的 IP 地址(私有 IP 和公網 IP 做轉換),NAT 技術不僅能解決 IP 地址不足的問題,而且還能夠有效地避免來自網絡外部的攻擊,隱藏并保護網絡內部的計算機。
  3. IPv6:IPv6 用 16 字節 128 位來表示一個 IP 地址,能夠大大緩解 IP 地址不足的問題。但? IPv6 并不是 IPv4 的簡單升級版,它們是互不相干的兩個協議,彼此并不兼容,因此目前? IPv6 還沒有普及。

6、私有 IP 地址與共網 IP 地址

如果一個組織內部組建局域網,IP?地址只用于局域網內的通信,而不直接連到?Internet上。理論上 使用任意的?IP?地址都可以,但是?RFC 1918?規定了用于組建局域網的私有?IP?地址。

  • 10.*,前 8 位是網絡號,共 16777216 個地址
  • 172.16. 到?172.31.,前 12 位是網絡號,共 1048576 個地址
  • 192.168.*,前 16 位是網絡號,共 65536 個地址。

包含在這個范圍中的,都成為私有?IP,其余的則稱為公網?IP(或全局 IP)

因為私有 IP 只能在局域網內出現,所以不同的子網內可能有相同的私有 IP,這樣就解決了 IP 不足的問題

可以通過命令:ifconfig 來查看我們這臺機器的私網 IP:

可以看到這個 IP 正好在第二種私網 IP 范圍內。


7、LAN 口 IP 與 WAN 口 IP

家用路由器:

  1. 對內:面對自己構建的子網
  2. 對外:自己本身也是別人構建子網的一個主機

路由器是可以構建局域網的,而且一定是橫跨兩個子網。所以路由器至少會配置兩個 IP,分別是 LAN 口(子網 IP)和 WAN 口:

  • 對內:LAN 口 IP:表示連接本地網絡的端口,局域網,主要與家庭網絡中的交換機、集線器或 PC 相連。
  • 對外:WAN 口 IP:表示連接廣域網的端口,自己所在上級子網給自己分配的 IP,一般指互聯網。
同一個局域網中,兩臺主機可以直接進行通信嗎?

可以。

家里要上網,首先需要做什么?
  1. 首先需要有運營商在家附近,且家附近有網絡覆蓋
  2. 聯系運營商進行光纖入戶
  3. 工作人員上門,調制解配器(貓),無線路由器
  4. 開戶,賬號,密碼,配置路由器(運營商認證的賬號、密碼)
  5. 配置路由器 —— 設置路由器的 WiFi 名稱 + 密碼(路由器認證的)
  6. 正常上網,按月/年交費
為什么我們平時使用微信、抖音、美團等 App,但卻每個月都充話費給了運營商呢?

基礎設施是運營商鋪設的。

為什么我們無法訪問 Google、fb 等網站呢?

收到了運營商的攔截。

  • 路由器 LAN 口連接的主機都從屬于當前這個路由器的子網中。
  • 不同的路由器,子網 IP 其實都是一樣的(通常都是 192.168.1.1),子網內的主機 IP 地址不能重復,但是子網之間的 IP 地址就可以重復了。
  • 每一個家用路由器,其實又作為運營商路由器的子網中的一個節點。這樣的運營商路由器可能會有很多級,最外層的運營商路由器,WAN 口 IP 就是一個公網 IP 了。
  • 如果希望我們自己實現的服務器程序,能夠在公網上被訪問到,就需要把程序部署在一臺具有外網 IP 的服務器上。這樣的服務器可以在阿里云/騰訊云上進行購買。

路由器天然的會構建局域網(子網)

私有網絡對應的 IP 是局部的,所以可以在不同的子網中出現重復(大大緩解 IP 不足的問題)

  1. 從運營商機房拉出的網線插在了家用路由器的 WAN 口上。
  2. 個人設備是插在家用路由器的 LAN 口上。

可以看到這兩個運營商路由器現在屬于一個子網中,如何讓他們劃分到不同的子網呢?

通過更改子網掩碼即可。


8、數據包的轉發流程(NAT 技術)

路由器要做的任務:

  1. 將報文中的源 IP 替換成路由器的 WAN 口 IP。
  2. 每經過一個運營商的內網路由器,都要做這個工作(公網路由不需要)。

由上圖可知數據剛出來的時候并不是直接到公網上,而是先交給家用路由器,再交給運營商路由器做內網轉發,轉發到一定程度后再轉發到公網,最后由公網到達目標服務器。

現在假設我們要從我們自己的主機訪問目標主機:

首先我們自己的主機判斷了目標 IP 并不在不在當前局域網,所以會把數據包直接轉給家用路由器,家用路由器也發現目標 IP 并不在不在當前局域網,所以就交給運營商路由器,運營商路由器直接連在公網,IP 是唯一確認的,所以就找到了目標服務器,把數據包交給目標服務器即可。

但這樣就會出現兩個問題:

  1. 私有 IP 不能出現在公網上,目標服務器收到的 src 就是個私有 IP。
  2. 因為私有 IP 在不同的子網里都有,那么響應要交給誰呢?

所以真實的轉發場景如下:當數據包到達家用路由器的時候,路由器會把源 IP 替換成 WAN 口 IP

對外路由器(運營商路由器)收到報文后,也會重復上面的操作:

然后就可以把這個替換過的報文轉發給目標服務器。此時往回響應的時候 src 就是運營商路由器,這樣就是到返回到哪個子網了

子網內的主機需要和外網進行通信,在轉發報文時,路由器不斷地將源 IP 首部中的 IP 地址在不同內網、不同層級的網絡節點中轉發,替換(替換成 WAN 口 IP),最終數據包中的 IP 地址成為一個公網 IP,這種技術稱為 NAT(Network Address Translation,網絡地址轉換)。


五、路由

1、數據路由過程

在復雜的網絡結構中找出一條通往終點的路線。

舉例幫助理解:假設在信息不發達的年代,我們來到了一個陌生的地方,當前只知道目的地名,那該如何到這個地方呢?最好的解決辦法就是詢問路人,那么這個人要么自己不知道但可以告訴我們該問誰,要么知道具體位置,要么他所處的地方就是目的地,那就不需要找了。

我們自己就是數據包,目的地就是目標 IP,問的路人就是路由器,而路人思考的過程就是查路由表路由的過程就是這樣一跳一跳(Hop By Hop)“問路”?的過程。所謂?“一跳”?就是數據鏈路層中的一個區間,具體在以太網中指從源?MAC?地址到目的?MAC?地址之間的幀傳輸區間。

決定將數據交付給下一跳路由器時,下一跳路由器一定和我在同一個局域網。

“一跳一跳” 的過程叫作局域網(子網)轉發。宏觀上而言,我們的網絡本質就是一個個子網構成的。

IP 數據包的傳輸過程也和問路一樣,這個過程中會遇到很多路由器,這些路由器會幫助數據包進行路由轉發,每當數據包遇到一個路由器后,對應路由器都會查看該數據的目的 IP 地址,路由器決定這個數據包是能直接發送給目標主機,還是需要發送給下一個路由器。依次反復,一直到達目標?IP?地址。

如何判定當前這個數據包該發送到哪里呢?
這個就依靠每個節點內部維護一個路由表。

路由器的查找結果可能有以下三種:

  1. 路由器經過路由表查詢后,得知該數據下一跳應該跳到哪一個子網。
  2. 路由器經過路由表查詢后,沒有發現匹配的子網,此時路由器會將該數據轉發給默認路由。
  3. 路由器經過路由表查詢后,得知該數據的目標網絡就是當前所在的網絡,此時路由器就會將該數據轉給當前網絡中對應的主機。


2、路由表

  • 每個路由器內部會維護一個路由表,在 Windows 下可以用命令:route PRINT?查看路由表。


  • Linux 下,可以通過命令:route 查看云服務器上對應的路由表。

如果目的 IP 命中了路由表,就直接轉發即可。

路由表中的最后一行主要由下一跳地址和發送接口兩部分組成,當目的地址與路由表中其它行都不匹配時,就按缺省路由條目規定的接口發送到下一跳地址。

  • Destination:目的網絡地址。

  • Gateway:下一跳地址。

  • Genmask:子網掩碼。

  • FlagsU 標志表示此條目有效(可以禁用某些條目),正在使用;G 標志表示此條目的下一跳地址是某個路由器的地址,默認網關(路由器)。沒有 G 標志的條目表示目的網絡地址是與本機接口直接相連的網絡,不必經路由器轉發。

  • Iface:發送接口。

這臺主機有兩個網絡接口:一個網絡接口連到 192.168.10.0/24 網絡,另一個網絡接口連到?192.168.56.0/24 網絡。

如果要發送的數據包的目的地址是 192.168.56.3 呢?
跟第一行的子網掩碼做與運算得到 192.168.56.0,與第一行的目的網絡地址不符。再跟第二行的子網掩碼做與運算得到 192.168.56.0,正是第二行的目的網絡地址,因此從 eth1 接口發送出去。由于 192.168.56.0/24 正是與 eth1 接口直接相連的網絡,因此可以直接發到目的主機,不需要經路由器轉發。
如果要發送的數據包的目的地址是 202.10.1.2 呢?
依次和路由表前幾項進行對比,發現都不匹配。按缺省路由條目,從 eth0 接口發出去,發往 192.168.10.1 路由器,由 192.168.10.1 路由器根據它的路由表決定下一跳地址。

(1)查詢路由表過程

當 IP 數據包到達路由器時,遍歷路由表的每一個條目,拿著目的 IP 依次與路由表中的子網掩碼 Genmask 進行 “按位與” 操作,來確定該報文要去的目標網絡,對比運算結果與目標網絡 Destination,如果一樣,將該數據包通過對應的發送接口 Iface 發出。

如果都沒有匹配上目標網絡 Destination,此時路由器就會將這個數據包發送到默認路由,也就是路由表中目標網絡地址中的 default。


(2)總結
  1. 遍歷路由表。

  2. 目的 IP & 子網掩碼,找到要去的目標網絡,沒找到就走默認網關。

  3. 通過 Iface 發送。

注意:IP 沒有解決設備轉發的具體功能,IP 提供的是轉發的策略,核心不是轉發,而是路徑選擇。


3、路由表生成算法(選學)

路由表可以由網絡管理員手動維護( 靜態路由), 也可以通過一些算法自動生成( 動態路由)。一些相關的生成算法, 例如距離向量算法, LS? 算法, Dijkstra? 算法等。

六、分片與組裝

在路由器之間傳遞的確實是 IP 報文,但真正在網線上跑的是 MAC 幀,MAC?幀是數據鏈路層的協議。


1、最大傳輸單元 —— MTU

MAC 幀作為數據鏈路層的協議,它會將 IP 傳下來的數據封裝成數據幀,然后發送到網絡當中。但 MAC 幀攜帶的有效載荷的最大長度是有限制的,也就是說 IP 交給 MAC 幀的報文不能超過某個值,也就是鏈路層一次可以轉發到網絡的報文大小的限制,這個值就叫作最大傳輸單元(MTU,可修改),大小一般是 1500 字節。


但是 IP 也不能決定單個報文的大小,在網絡中決定報文大小的是 TCP。
所以 IP 層自己想了個辦法:如果 IP 層要傳送的數據超過了 1500 字節,那么就需要先在 IP 層對該數據進行分片,然后再將分片后的數據交給下層 MAC 幀進行發送。

發送方的 IP 層負責分片,接收方的 IP 層負責封裝。

而分片是通過 IP 協議報頭的這三個字段完成的:

  • 16 位標識:唯一的標識主機發送的報文,如果數據在 IP 層進行了分片,那么每一個分片對應的 id 都是相同的。
  • 3 位標志字段:第一位保留,表示暫時沒有規定該字段的意義。第二位表示禁止分片,表示如果報文長度超過 MTU,IP 模塊就會丟棄該報文。第三位表示 “更多分片”,如果報文沒有進行分片,則該字段設置為 0,如果報文進行了分片,則除了最后一個分片報文設置為 0 以外,其余分片報文均設置為 1。
  • 13 位片偏移:分片相對于原始數據開始處的偏移,表示當前分片在原數據中的偏移位置,實際偏移的字節數是這個值 ×8 得到的。因此除了最后一個報文之外,其他報文的長度必須是 8 的整數倍,否則報文就不連續了。
如何識別報文和報文之間的不同?

通過 16 位標識,不同的報文標識不同,相同報文的分片具有相同的標識。

一個報文沒有被分片的標志是什么?

更多分片的標志位是 0,13 位片偏移也為 0。

  1. if(報文 -> 更多分片 & 0x1) return 分片的
  2. else if(報文 -> 片偏移 > 0) return 分片的
  3. else return 獨立的報文
AI寫代碼

2、分片流程

如何識別出哪些分片是開始,哪些是中間,哪些是結尾?
  • 開始:更多分片 1,片偏移?0。
  • 中間:更多分片 1,片偏移不是 0。
  • 結尾:更多分片 0,片偏移不是 0。
中間報文有多個,那么如何保證收全了?

根據偏移量進行升序排序,結合?偏移量 + 自身大小 = 下一個報文的偏移量?掃描整個報文,如果不匹配,中間一定會有丟失,如果成功計算到結尾,就一定收取完整了。

假設 IP 層要發送 2980 字節大小的數據,如果 IP 報頭不含選項字段,那么加上報頭就是 3000 字節,超過了最大傳輸單元,需要切分。這里要注意每個切分下來的都是純數據,每部分數據都要添加報頭。可以先切下 1500 字節(含原始的報頭),然后還剩下 1500 的純數據,再切下 1480 的純數據,加上 20 字節的報頭,剛好構成 1500 字節,還剩下 20 字節的純數據,把這 20 個字節純數據也加上報頭,就是 40 字節。最終就分成了三部分,總長度分別為:1500,1500,40。

接下來就填寫三個報頭的三個字段:

分片之前,一定是一個獨立的 ip 報文。

分片之后,不能只進行直接分片,然后讓報頭跟著第一個報頭就行(錯誤?),為了支持組裝,所以是每一個分片都要有 IP 報頭(正確?


3、組裝流程

通過 16 位標識來確定這些報文曾經屬于一個報文,通過更多分片加上 13 位片偏移來確定該報文有沒有被切分以及首尾以及順序。

先找到分片報文中 13 位片偏移為 0 的分片報文,然后提取出其 IP 報頭當中的 16 位總長度字段,通過計算即可得出下一個分片報文所對應的 13 位片偏移,按照此方式依次將各個分片報文拼接起來。
直到拼接到一個 “更多分片” 標志位為 0 的分片報文,此時表明分片報文組裝完畢。


4、分片的影響(壞處)

分片行為不是主流,在網絡通信里,嚴重推薦不分片。原因如下:

  1. 在網絡層分片和組裝的過程,上層(傳輸和應用)并不知道。
  2. 分片會增加丟包的概率。因為一個報文被切成了多個報文,只要有一個報文丟失了就會造成拼接失敗,因為不知道是哪個報文丟了(TCP 不關心分片),而網絡層有校驗和,如果報文丟棄了,就導致傳輸層(比如 TCP,而 UDP 就直接丟包了,對 UDP 的影響更大)重傳,對整個報文進行重傳。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/77806.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/77806.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/77806.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于 Vue 的Tiptap 富文本編輯器使用指南

目錄 🧰 技術棧 📦 所需依賴 📁 文件結構 🧱 編輯器組件實現(components/Editor.vue) ? 常用操作指令 🧠 小貼士 🧩 Tiptap 擴展功能使用說明(含快捷鍵與命令&am…

統計圖表ECharts

統計某個時間段,觀看人數 ①、數據表 ②、業務代碼 RestController RequstMapping(value"/admin/vod/videoVisitor") CrossOrigin public class VideoVisitorController{Autowriedprivate VideoVisitorService videoVisitorService;//課程統計的接口…

ubuntu 安裝 redis server

ubuntu 安裝 redis server sudo apt update sudo apt install redis-server The following NEW packages will be installed:libhiredis0.14 libjemalloc2 liblua5.1-0 lua-bitop lua-cjson redis-server redis-toolssudo systemctl start redis-server sudo systemctl ena…

【白雪講堂】[特殊字符]內容戰略地圖|GEO優化框架下的內容全景布局

📍內容戰略地圖|GEO優化框架下的內容全景布局 1?? 頂層目標:GEO優化戰略 目標關鍵詞: 被AI理解(AEO) 被AI優先推薦(GEO) 在關鍵場景中被AI復讀引用 2?? 三大引擎邏輯&#x…

NVIDIA 自動駕駛技術見解

前言 參與 NVIDIA自動駕駛開發者實驗室 活動,以及解讀了 NVIDIA 安全報告 自動駕駛 白皮書,本文是我的一些思考和見解。自動駕駛技術的目標是為了改善道理安全、減少交通堵塞,重塑更安全、高效、包容的交通生態。在這一領域,NVI…

OpenCV day6

函數內容接上文:OpenCV day4-CSDN博客 , OpenCV day5-CSDN博客 目錄 平滑(模糊) 25.cv2.blur(): 26.cv2.boxFilter(): 27.cv2.GaussianBlur(): 28.cv2.medianBlur(): 29.cv2.bilateralFilter(): 銳…

Function calling, 模態上下文協議(MCP),多步能力協議(MCP) 和 A2A的區別

背景闡述 本文大部分內容都是基于openAI 的 chatGPT自動生成。作者進行了一些細微的調整。 LLM 帶來了很多思維的活躍,基于LLM,產生了很多應用,很多應用也激活了LLM的新的功能。 Function calling,MCP(Modal Contex…

火山RTC 5 轉推CDN 布局合成規則

實時音視頻房間&#xff0c;轉推CDN&#xff0c;文檔&#xff1a; 轉推直播--實時音視頻-火山引擎 一、轉推CDN 0、前提 * 在調用該接口前&#xff0c;你需要在[控制臺](https://console.volcengine.com/rtc/workplaceRTC)開啟轉推直播功能。<br> * 調…

力扣面試150題--插入區間和用最少數量的箭引爆氣球

Day 28 題目描述 思路 初次思路&#xff1a;借鑒一下昨天題解的思路&#xff0c;將插入的區間與區間數組作比較&#xff0c;插入到升序的數組中&#xff0c;其他的和&#xff08;合并區間&#xff09;做法一樣。 注意需要特殊處理一下情況&#xff0c;插入區間比數組中最后一…

【Java面試筆記:基礎】4.強引用、軟引用、弱引用、幻象引用有什么區別?

1. 引用類型及其特點 強引用(Strong Reference): 定義:最常見的引用類型,通過new關鍵字直接創建。回收條件:只要強引用存在,對象不會被GC回收。示例:Object obj = new Object(); // 強引用特點: 強引用是導致內存泄漏的常見原因(如未及時置為null)。手動斷開引用:…

ycsb性能測試的優缺點

YCSB&#xff08;Yahoo Cloud Serving Benchmark&#xff09;是一個開源的性能測試框架&#xff0c;用于評估分布式系統的讀寫性能。它具有以下優點和缺點&#xff1a; 優點&#xff1a; 簡單易用&#xff1a;YCSB提供了簡單的API和配置文件&#xff0c;使得性能測試非常容易…

基于SpringBoot的校園賽事直播管理系統-項目分享

基于SpringBoot的校園賽事直播管理系統-項目分享 項目介紹項目摘要管理員功能圖用戶功能圖項目預覽首頁總覽個人中心禮物管理主播管理 最后 項目介紹 使用者&#xff1a;管理員、用戶 開發技術&#xff1a;MySQLJavaSpringBootVue 項目摘要 隨著互聯網和移動技術的持續進步&…

Nginx?中間件的解析

目錄 一、Nginx的核心架構解析 二、Nginx的典型應用場景 三、Nginx的配置優化實踐 四、Nginx的常見缺陷與漏洞 一、Nginx的核心架構解析 ??事件驅動與非阻塞IO模型?? Nginx采用基于epoll/kq等系統調用的事件驅動機制&#xff0c;通過異步非阻塞方式處理請求&#xff0c;…

杭州小紅書代運營公司-品融電商:全域增長策略的實踐者

杭州小紅書代運營公司-品融電商&#xff1a;全域增長策略的實踐者 在品牌競爭日趨激烈的電商領域&#xff0c;杭州品融電商作為一家專注于品牌化全域運營的服務商&#xff0c;憑借其“效品合一”方法論與行業領先的小紅書代運營能力&#xff0c;已成為眾多品牌實現市場突圍的重…

【映客直播-注冊/登錄安全分析報告】

前言 由于網站注冊入口容易被黑客攻擊&#xff0c;存在如下安全問題&#xff1a; 暴力破解密碼&#xff0c;造成用戶信息泄露短信盜刷的安全問題&#xff0c;影響業務及導致用戶投訴帶來經濟損失&#xff0c;尤其是后付費客戶&#xff0c;風險巨大&#xff0c;造成虧損無底洞…

Android audio_policy_configuration.xml加載流程

目錄 一、audio_policy_configuration.xml文件被加載流程 1、AudioPolicyService 創建階段 2、createAudioPolicyManager 實現 3、AudioPolicyManager 構造 4、配置文件解析 loadConfig 5、核心解析邏輯 PolicySerializer::deserialize 二、AudioPolicyConfig類解析 1、…

使用 Docker 安裝 Elastic Stack 并重置本地密碼

Elastic Stack&#xff08;也被稱為 ELK Stack&#xff09;是一個非常強大的工具套件&#xff0c;用于實時搜索、分析和可視化大量數據。Elastic Stack 包括 Elasticsearch、Logstash、Kibana 等組件。本文將展示如何使用 Docker 安裝 Elasticsearch 并重置本地用戶密碼。 ###…

Unitest和pytest使用方法

unittest 是 Python 自帶的單元測試框架&#xff0c;用于編寫和運行可重復的測試用例。它的核心思想是通過斷言&#xff08;assertions&#xff09;驗證代碼的行為是否符合預期。以下是 unittest 的基本使用方法&#xff1a; 1. 基本結構 1.1 創建測試類 繼承 unittest.TestC…

git 版本提交規范

Git 提交規范&#xff08;Git Commit Message Convention&#xff09;是為了讓項目的提交歷史更加清晰、可讀、便于追蹤和自動化工具解析。常見的規范之一是 Conventional Commits&#xff0c;下面是一個推薦的格式規范&#xff1a; &#x1f31f; 提交信息格式&#xff08;Con…

stat判斷路徑

int stat(const char *pathname, struct stat *buf); pathname&#xff1a;用于指定一個需要查看屬性的文件路徑。 buf&#xff1a;struct stat 類型指針&#xff0c;用于指向一個 struct stat 結構體變量。調用 stat 函數的時候需要傳入一個 struct stat 變量的指針&#xff0…