目錄
0.引入
1.以太網幀格式
2.重談局域網轉發的原理(基于協議)
小結
3.認識MTU
3.1MTU對IP協議的影響
3.2MTU對UDP協議的影響
3.3MTU對于TCP協議的影響
0.引入
在去年的這篇文章中,我們有對網絡進行過一個概述[Linux#47][網絡] 網絡協議 | TCP/IP模型 | 以太網通信,現在我們來詳細講解一下其中的 數字鏈路層部分
網絡: 先決策識別,后執行
在IP協議說過在路由器上是確實根據IP報文目的IP路由的,
但其實真正在網絡上跑的并不是IP報文,而是MAC幀。
?
現在我們已經知道數據可以經過路由選擇從主機B跨網絡送到主機C
- 路上有運營商搞的內網
- 有運營商搞的公網
- 整個網絡按照子網掩碼以及運營商劃分好的網絡區塊構建的拓撲結構(本質就是圖 算法了)幫我們進行路由,路由器中配有路由表。(文件中也有 頁表)
整個路由轉發的過程我們已經很清楚了。
現在的問題是,要把數據跨網絡送到主機C,要先經過路徑選擇
- 把數據交給主機B直接相連的下一跳路由器,雖然這個路由器也要進行路由選擇
- 但是在怎么路徑選擇它也依舊要將路由器中的數據在交付給和它直接相連的下一跳路由器
- 同理,每一個設備都是如此。
- 所以你要把數據跨網絡路徑選擇送到主機C,你首先要解決的是要先把數據從主機B交給和它直接相連的某一個節點
至于為什么不是路由器E,路由G,因為我們有路徑選擇。
一旦我們選擇好了那怎么把數據交給路由器F呢?所以我們就需要有另一個協議了。
- 另外把數據從主機B交給路由器F前提是兩者屬于同一個網端,同理從某個路由器交給下一跳路由器,兩者都需要在同一個網段。
- 所以你要進行跨網絡傳輸,你要先解決在同一個局域網內將主機B中的數據交給路由器F,然后路由器F在交給路由器G等等。
所以跨網絡傳輸的本質,是無數個局域網(子網)轉發的結果!!!
所以要徹底理解跨網絡轉發,首先要理解局域網中報文的轉發原理
關于局域網轉發原理我們在網絡基礎一學過,這里我們首先要有一個共識,在同一個局域網的主機,可以直接通信!
一個故事
老師點名張三,全班同學都聽到了,每一個同學都把張三的報文報頭解析和自己做對比,發現不是叫自己,張三發現是自己,回答說“到”,老師和張三之間進行了通信,班上有很多吃瓜群眾
- 在這所公共場所教室里面信的時候,老師認不認為在和張三直接通信呢?當然認為。
- 老師認不認為在和張三一對一直接通信呢?老師認為!
所以實際在局域網看起來兩臺主機在一對一直接通信,但是其他主機也都會收到,但是經過比對發現不是給我發的,數據鏈路層就把該報文丟棄。所以看起來就是兩臺主機在一對一直接通信!
從上面故事我們還可以提出一條消息,每臺主機都要有唯一的標識符,因為有了這個唯一標識符才能區分這個消息是否是轉給我的。
1.以太網幀格式
數據在經過路由選擇發現它要去該局域網的出口路由器中,所以它要重新封裝MAC幀,那IP就要把報文交給它的下一層以太網遵守的協議MAC幀。
所以IP報文要封裝成MAC幀,所以接下來了解MAC幀的報頭
以太網的幀格式如下所示:
很明顯前面6 6 2 以及后面4字節屬于MAC幀報頭,一頭一尾夾在中間的數據是有效載荷(IP報頭+有效載荷)
?
如何將報頭和有效載荷分離?
- MAC幀采用固定大小報頭。收到一個MAC幀只需要將前面14字節后面4字節去掉,剩下的就是有效載荷。
如何分用
- MAC幀有個類型字段
- 類型是 0800 代表有效載荷是IP數據報
- 0806 代表ARP請求/應答
- 8035 代表RARP請求/應答,所以有幀類型就可以區分。
剛才說每臺主機都必須要有唯一標識,這個標識如何理解?
- 每臺機器至少配一個網卡,每張網卡都要有唯一的一個序列號,這個序列號稱為該網卡的MAC地址,這個MAC地址在全球范圍內具有唯一性
- 長度是48位,是在網卡出廠時固化的。源地址和目的地址指的就是網卡的硬件地址(也叫MAC地址),表示從哪來到哪去。
幀末尾是CRC校驗碼。
2.重談局域網轉發的原理(基于協議)
現在一個局域網有7臺主機,地址從m1到m7,現在m1想把數據發給m7 怎么做呢?
它一定要自己封裝MAC幀。數據上層交付下來到了數據鏈路層封裝MAC幀,
然后發送到局域網中,問題來了,m2,m3,m4,m5,m6,m7每一臺主機都能收到這個MAC幀,那每一臺主機數據鏈路層要不要接收這個發出去的MAC幀呢?要!
- 每一臺主機數據鏈路層也都要做報頭和有效載荷分離,當想向上交付時,首先要確認這個報文是不是要發給自己的,以m2為例,它首先確認這個MAC幀的目的MAC地址,發現是m7,但自己是m2
- 所以m2在自己的數據鏈路層直接把該報文丟棄,當丟棄了它也沒有向上交付的動作,所以上層也不知道m2曾經收到MAC幀。
- 同理m2,m3,m4,m5,m6都會把幀拿上去然后對比之后發現不是發給自己的都會丟棄。
同理m7作為當前局域網中的一臺主機,它也會收到這個MAC幀,然后數據鏈路層做報頭和有效載荷分離,然后識別到目的MAC地址是自己,然后根據幀類型把有效載荷向上交付。
至此m1給m7發送消息,m7收到了。
?
然后m7向上解包分用直到交付給應用層,應用層處理好之后在向下交付到TCP層,IP層,直到在到數據鏈路層封裝成MAC幀,給m1應答。
- 封裝MAC幀之后,同樣也是發送到局域網里,同理m1,m2,m3,m4,m5,m6都會收到,除m1之后,其他在數據鏈路層在報頭和有效載荷分離發現目的mac地址不是自己就給扔掉了上層也不知道自己曾經收到了MAC幀。
- 同理m1收到后也做報頭和有效載荷分離,對比之后發現目的mac地址是自己,然后就把有效載荷交付給上一層,然后解包分用直到交給應用層,這樣m7給m1應答完成。
所以以太網通信原理非常簡單,所有的信息其實都會被局域網所有主機收到,只不過絕大部分主機在數據鏈路層對比目的mac地址發現不是自己,所有主機把數據報文全部丟棄。
只有是自己的才會向上交付,至此就完成了局域網通信的一般原理。
所以我們就可以這么理解
小結
局域網中所有的主機其實都能收到對應mac,只不過大部分主機在自己的數據鏈路層通過對比數據幀中的目的mac地址和自己的mac地址是否相等,來決策要不要進行后序處理!
- 在局域網中網卡有一種模式,稱之為混雜模式
- 默認網卡是沒有開啟混雜模式的,特點:不放棄任何數據幀直接向上交付。這也是大部分局域網抓包工具原理!
- 一個局域網中,這個網絡是被所有主機共享的,所有主機都能夠發信息,m1發,m3也可以發,m5也可以發,如果同一時間大家都發就會導致很嚴重的數據碰撞問題。
所以在局域網中,任何時刻,只能有一個主機發信息,如果多個消息被同時發送,會導致局域網中的數據發生碰撞,這個數據就成了無效數據。
那m1發送的,m1如何知道發送碰撞了?
- m1發送的時候自己也能收到,它發現自己發的和收的不一樣,那CRC校驗通不過,不就是數據發送碰撞了嘛。
所以一個局域網,也稱為一個碰撞域
那如何保證在任何一個時刻只允許一個主機發送呢?
- 不同的局域網標準有不同的實現方案,有一種叫令牌環,就好比在局域網中流轉一部分令牌數據,只有持有令牌的人才可以發信息。(這是一個重要的解決碰撞的思想,借助令牌)
- 一個主機發信息需要把令牌發送到局域網中轉給下一臺主機。
- 另一種是以太網,發數據如果監測到碰撞了就暫時不發數據等一等,然后在發送。
- 所以重傳可不只有tcp,在數據鏈路層發送碰撞了也要進行重傳。這種策略我們稱為主機的碰撞檢測和碰撞避免。
如何重新看待局域網(以系統角度):
- 局域網本質要被該局域網所有主機共享,而為了保證正常通信任何時刻只能有一臺主機能夠進行通信,所以局域網在我看來就是一種臨界資源
- 碰撞檢測+碰撞避免,任何一個時刻只有一臺主機能夠向臨界資源中寫入數據,就是臨界區!令牌環不就是鎖嗎。
那現在有一個問題:
局域網能不能很大?為什么?
- 不能,局域網太大意味著主機很多,也就意味著任何時刻發送碰撞的概率就增加了!
如果局域網就是很大,有沒有辦法緩解碰撞概率呢?
- 在網絡中可以有一種設備叫做交換機,工作在數據鏈路層。
比如m1給m7發送消息,m2同時刻給m6發送消息,在交換機的一側發生了碰撞,那交換機能夠識別局部性的碰撞,對碰撞數據不做轉發。 - 一旦把這個數據轉發過去了那所有主機都識別到數據發生碰撞,然后執行碰撞檢測和碰撞避免,所以會影響交換機右側對應的數據發送。
- 所以交換機識別碰撞了對碰撞數據不轉發,但交換機另一側沒有問題,所以另一側正常發送數據。
- 所以交換機就有效的對碰撞域做了分割。其次如果是交換機一側在互相發送消息,比如m1給m6發送消息,交換機能夠識別出來當前通信的兩臺主機是我交換機劃分碰撞域的左側
所以不對正常數據做轉發,也就說不把數據轉發到我交換機右側。也就是說右側的主機正常通信把,右側的碰撞概率也就降低了。交換機的核心工作:劃分碰撞域!
因為有碰撞域,所以一臺主機發送數據的時候,發送數據量長了好,還是短了好?為什么?
- 如果發送數據量非常長,這意味在轉發的數據在網絡的時間很長,發送碰撞概率增大。
- 如果發送數據量很短,一個數據發送很多次,發送碰撞概率也會增大。
- 所以數據幀有一個傳輸數據大小的范圍。規定有效載荷長度最大不超過1500字節。最小不超過46字節(不夠MAC幀做填充)。
由于有這個規定,所以導致IP報文可能要分片。
對比理解MAC地址和IP地址
- IP地址描述的是路途總體的 起點 和 終點;
- MAC地址描述的是路途上的每一個區間的起點和終點;
主機將數據交付給下一跳(下一跳的是主機還是路由器等其他節點)
前提一定是 該數據幀被路由過,因為網絡層在數據鏈路層的上層。
- 還有個 有意思的點,就是我們手機開熱點 也會變成一個路由器了
3.認識MTU
MTU相當于發快遞時對包裹尺寸的限制. 這個限制是不同的數據鏈路對應的物理層, 產生的限制.
- 以太網幀中的數據長度規定最小46字節,最大1500字節,ARP數據包的長度不夠46字節,要在后面補填充位;
- 最大值1500稱為以太網的最大傳輸單元(MTU),不同的網絡類型有不同的MTU;
- 如果一個數據包從以太網路由到撥號鏈路上,數據包長度大于撥號鏈路的MTU了,則需要對數據包進行分片(fragmentation);
- 不同的數據鏈路層標準的MTU是不同的;
3.1MTU對IP協議的影響
由于數據鏈路層MTU的限制, 對于較大的IP數據包要進行分包.
- 將較大的IP包分成多個小包, 并給每個小包打上標簽;
- 每個小包IP協議頭的 16位標識(id) 都是相同的;
- 每個小包的IP協議頭的3位標志字段中, 第2位置為0, 表示允許分片, 第3位來表示結束標記(當前是否是最后一個小包, 是的話置為1, 否則置為0);
- 到達對端時再將這些小包, 會按順序重組, 拼裝到一起返回給傳輸層;
- 一旦這些小包中任意一個小包丟失, 接收端的重組就會失敗. 但是IP層不會負責重新傳輸數據;
IP報文如何分片和組裝,在IP協議的文章中我們寫到過,這里不再細說。
現在有一個問題,是不是只有發送端主機來分片,路上的其他節點(路由器)會不會也對數據做分片呢?
有可能!大家用的都是TCP/IP,中間的路由器也是工作在網絡層也有分片的能力,可能MTU也有分片的需求。
- 可能發送方主機規定MTU1500,不排除有些路由器MTU規定是500。
- 所以IP報頭的16位標識,3位標記,13位片偏移量同樣也支持在路上進行分片,然后組裝。
從主機A把數據跨網絡送到主機D可能并不是只有一條路徑供選擇
- 但是如果主機A在發送數據時將IP報文按1500字節分好片之后,并且將分片后的IP報頭中3個標記中第二個標記設為1表示不可分片
- 在進行轉發這些分片的時候,一旦遇到路由器想要在把分片在進行分片的時候,但是我不讓它進行分片,那么這個路由器就把這個分片就直接丟棄了
那發送方就要進行超時重傳,就要重新進行路徑選擇,就可能找到一條允許我直接按照1500字節從頭發到尾的路徑,所以就能找到一個叫做 “最大吞吐量” 的路徑。
- 所以 曾經說過IP報頭里有一個禁止分片的標記位,這玩意可以在路上確定是否有些路由器摳摳搜搜,這樣在這個轉發的路上只會選擇能夠轉發1500字節的路由器了。
- 這個標記位是支持我們進行各種路由選擇策略之一的選項。
3.2MTU對UDP協議的影響
- 一旦UDP攜帶的數據超過1472(1500 - 20(IP首部) - 8(UDP首部)), 那么就會在網絡層分成多個IP數據報.
- 這多個IP數據報有任意一個丟失, 都會引起接收端網絡層重組失敗. 那么這就意味著, 如果UDP數據報在網絡層被分片, 整個數據被丟失的概率就大大增加了.
3.3MTU對于TCP協議的影響
在IP協議說過,分片并不好,那如何在進行數據包轉發中不要出現分片問題呢?
前面說過IP不能決定單個報文大小,真正在網絡中決定單個報文大小的是TCP。那TCP是如何做到減少IP出現分片情況的呢?
- MAC規定有效載荷最大不超過1500字節,那IP交給MAC的IP報文:IP報頭+有效載荷 = 1500,IP標準報頭長度20字節,那有效載荷就是1480。這個有效載荷是上層TCP報文:TCP報頭+有效載荷 = 1480,TCP標準報頭長度也是20字節,那有效載荷是1460。
MAC規定有效載荷最大不超過1500字節,所以從根上要從TCP來解決,TCP你自己發送報文時,規定單個報文有效載荷大小不要超過1460。這樣添加TCP報頭,IP報頭到MAC幀就不會超過1500。
所以滑動窗口=min(擁塞窗口,對方接收能力),那為什么不直接一次打包發送,而是把滑動窗口范圍分成多個報文段發送?
原因是網絡不允許一次發送太大的單個數據段!
所以這些協議之間會互相影響!
我們把基于MTU1500字節的規定,最后影響了TCP發送數據時最多發送1460這樣的數據報文,我們叫做MSS(最大段尺寸),就是TCP它的有效載荷最大是多少。
- TCP的一個數據報也不能無限大, 還是受制于MTU. TCP的單個數據報的最大消息長度, 稱為MSS(Max Segment Size);
- TCP在建立連接的過程中, 通信雙方會進行MSS協商.
- 最理想的情況下, MSS的值正好是在IP不會被分片處理的最大長度(這個長度仍然是受制于數據鏈路層的MTU).
- 雙方在發送SYN的時候會在TCP頭部寫入自己能支持的MSS值.
- 然后雙方得知對方的MSS值之后, 選擇較小的作為最終MSS.
- MSS的值就是在TCP首部的40字節變長選項中(kind=2);
MSS和MTU的關系
?
查看硬件地址(MAC地址)和MTU
使用ifconfig命令, 即可查看ip地址, mac地址, 和MTU;
關于MAC幀協議所有內容到此結束。
我們現在整個網絡的思想結構以及建立好了,下面就是對這個結構進行縫縫補補。
在此之前我們結合前面學的知識把整個網絡發送過程串一下。然后引出下一個話題。
在整個網絡發送過程,難道沒有發現一個問題嗎?把數據從主機A跨網絡送到主機D,要經過各種路由選擇。
- 但先別跨網絡了并且也不能憑空飛過去,網線只要在物理層上,就必須把數據從最上層交給物理層,然后要解決數據從A跨網絡到D
- 要先解決數據從主機A送到路由器A,然后再從路由器A送到路由器E,所以在局部上任何一個主機進行下一跳的時候,它和它下一跳一定屬于同一個局域網
所以跨網絡通信的本質,不就是在一個一個局域網跳轉嗎,也正是在一個一個局域網跳轉最終才構成了宏觀的大的跨網絡傳輸效果。
- IP協議的講張三去清華大學的故事在繼續,張三要去清華大學,不斷的問,最后問到清華大學門口保安大爺,大爺說這就是清華大學,曾經說過數據經過路由目的是找到目標網絡嗎?
- 并不是,IP=目標網絡+目的主機,所以你要去的其實主機,只不過為了到達主機你要先到達目標網絡,現在你已經到達了要去的目標網絡的入口路由器處,接下來你問保安大爺,那我現在19號宿舍樓怎么走,大爺說你先這樣走在那樣走就到了。
所以此時數據包千里迢迢把自己送到了另一個子網中的入口路由器處
?
現在要把這個數據包交給這個目標網絡中的目標主機了,根據我們所學一定能保證我要去的目標主機一定在對應的子網中,因為我們的網絡號是一樣的。
- 可是入口路由器要把數據交給和它在同一網段的主機 C,注定了這是一個局域網通信
- 路由器在自己的網絡層拿到該數據報文后,查看路由表發現你要去的主機就在當前局域網,就注定了這個報文要被封裝成MAC幀然后發送給目標主機 C
可是要封裝成MAC幀,我們必須要知道主機 C 的MAC地址!
- 可是在前面再說MAC幀的時候我們默認了知道每臺主機的MAC幀地址,這是站在上帝視角知道的
- 可是局域網不止一臺機器,你憑什么知道主機 C 的MAC地址呢?
- 并且從上到下所傳的報文里也根本沒有主機 C 的MAC地址!你知道主機 C 的IP地址!
所以你想從你收到的報文中拿是不可能的。
一般而言路由器是一定認識主機 C 的,但是憑什么?
所以此時需要有一個過程,讓路由器設備,認識主機 C,本質上是獲取主機 C 的MAC地址!
- 因為只有知道主機 C 的MAC地址才能夠把我收到的數據包向下封裝成MAC幀發送給主機 C。
- 所以路由器憑什么認識和它處在同一個網絡其他主機的MAC地址,包括之前說的m1給m7發送消息,憑什么m1就知道m7的mac地址呢?
所以我們此時需要局域網通信的又一種協議,該協議叫做ARP協議!
我們將在下篇文章中詳細講到,下篇文章見~