據(jù)鏈路層全解析:幀結(jié)構(gòu)、CRC校驗(yàn)與交換機(jī)工作原理)
計(jì)算機(jī)網(wǎng)絡(luò)學(xué)到第二篇恭喜你熬過了概述和物理層那些相對比較“干”的內(nèi)容總算摸到一點(diǎn)真正協(xié)議的門道了。這篇筆記我結(jié)合了當(dāng)時(shí)上課的講義、教材和課后實(shí)踐把第二站的內(nèi)容整理成一份能直接照著學(xué)的路線圖。上一篇我們聊了分層模型、電路交換和分組交換這些基礎(chǔ)這一篇進(jìn)入數(shù)據(jù)鏈路層也就是協(xié)議棧里“第一層有腦子”的地方。數(shù)據(jù)鏈路層這層我剛開始學(xué)的時(shí)候總覺得它很“憋屈”——上面有網(wǎng)絡(luò)層發(fā)號施令下面有物理層干搬比特的粗活它夾在中間像極了一個(gè)傳話的秘書。后來自己動手抓包、用交換機(jī)做實(shí)驗(yàn)才意識到這層才是整個(gè)網(wǎng)絡(luò)通信里最講究“規(guī)矩”的地方幀怎么封、錯怎么查、沖突怎么解決、消息怎么點(diǎn)名確認(rèn)全在這一層體現(xiàn)。這篇筆記適合兩類人看一類是正在自學(xué)歷計(jì)算機(jī)網(wǎng)絡(luò)、被各種概念搞得頭大的初學(xué)者另一類是已經(jīng)工作、想回頭系統(tǒng)補(bǔ)一遍基礎(chǔ)理論的開發(fā)者或運(yùn)維。相信我把數(shù)據(jù)鏈路層啃透后面學(xué)網(wǎng)絡(luò)層和傳輸層會輕省很多。1. 這一篇到底在學(xué)什么從整體定位拆解學(xué)習(xí)主線1.1 數(shù)據(jù)鏈路層在網(wǎng)絡(luò)里的真實(shí)角色先從一個(gè)最簡單的問題入手物理層已經(jīng)把比特流從一個(gè)設(shè)備搬到了另一個(gè)設(shè)備上傳輸過程是不是就完事大吉了不是。物理層只負(fù)責(zé)“把0和1送出去”但它并不知道這一串比特該從哪里開始讀、到哪里結(jié)束也不知道中途有沒有被噪聲干擾傳錯更不知道這條鏈路上同時(shí)有多少個(gè)設(shè)備在說話。數(shù)據(jù)鏈路層干的事就是把物理層送來的原始比特流“切成一段一段的”給每一段加上頭部和尾部變成一個(gè)一個(gè)的“幀”然后交給物理層發(fā)送。這個(gè)過程叫作封裝成幀。幀的概念可以類比快遞包裹你要寄一件衣服不會直接把衣服扔給快遞員而是先套一個(gè)袋子填上寄件人、收件人、物品說明然后打包。幀結(jié)構(gòu)里的“地址”“類型”“校驗(yàn)碼”干的就是這些事。除了封裝數(shù)據(jù)鏈路層還要保證“接收方能看清楚每個(gè)包的邊界在哪里”這叫透明傳輸保證傳出去的數(shù)據(jù)能發(fā)現(xiàn)錯誤這叫差錯檢測如果鏈路是多個(gè)設(shè)備共享的還要決定“誰先說話”的問題這叫介質(zhì)訪問控制。這幾件事就是整層學(xué)習(xí)的主線。1.2 用一條邏輯線串起整層知識很多同學(xué)學(xué)這層會學(xué)成一盤散沙今天背幀格式明天看CRC后天搞CSMA/CD最后發(fā)現(xiàn)什么都記不清。我的經(jīng)驗(yàn)是把數(shù)據(jù)鏈路層當(dāng)成一個(gè)“點(diǎn)對點(diǎn)投遞系統(tǒng)”來理解所有知識點(diǎn)都能串起來先解決包工包料的問題——發(fā)送方怎么把網(wǎng)絡(luò)層下來的IP數(shù)據(jù)報(bào)包成能在鏈路上跑的幀這是封裝成幀。再解決邊界識別的問題——數(shù)據(jù)內(nèi)容里如果恰好出現(xiàn)了和幀首尾一樣的標(biāo)志字節(jié)怎么避免接收方誤判這是透明傳輸。然后解決傳錯的問題——幀發(fā)出去了接收方怎么知道這幀有沒有被干擾這是差錯檢測CRC循環(huán)冗余校驗(yàn)。接著解決多設(shè)備搶道的問題——如果幾個(gè)設(shè)備共享一條鏈路同時(shí)發(fā)數(shù)據(jù)不就撞車了嗎這是介質(zhì)訪問控制典型代表是CSMA/CD。最后是接口問題——MAC地址和IP地址到底怎么配合工作的這涉及ARP協(xié)議也是理解“二層轉(zhuǎn)發(fā)”和“三層路由”差異的關(guān)鍵。把這五個(gè)問題按順序想清楚整章內(nèi)容就自然串成一條線了。我學(xué)的時(shí)候習(xí)慣畫一張流程圖發(fā)送端從網(wǎng)絡(luò)層拿到數(shù)據(jù)報(bào)加幀頭幀尾、算FCS、發(fā)出去接收端收到后先查FCS、再確認(rèn)邊界、最后拆幀把數(shù)據(jù)交給網(wǎng)絡(luò)層。學(xué)習(xí)時(shí)你自己動手畫一遍這張圖比看十遍課本都有用。2. 幀結(jié)構(gòu)、CRC校驗(yàn)與差錯檢測最容易卡住的三個(gè)細(xì)節(jié)2.1 以太網(wǎng)幀結(jié)構(gòu)深度拆解我們平時(shí)接觸最多的就是以太網(wǎng)所以先從以太網(wǎng)幀說起。以太網(wǎng)幀的標(biāo)準(zhǔn)結(jié)構(gòu)是前導(dǎo)碼加幀體幀體一共至少64字節(jié)分為幾個(gè)字段字段長度作用前導(dǎo)碼8字節(jié)同步時(shí)鐘不屬于幀本身發(fā)送時(shí)由硬件自動添加目的MAC地址6字節(jié)收件人地址指明幀要送給哪個(gè)網(wǎng)卡源MAC地址6字節(jié)寄件人地址標(biāo)明這幀是從哪塊網(wǎng)卡發(fā)出的類型/長度2字節(jié)例如0x0800表示上層是IPv40x0806表示上層是ARP數(shù)據(jù)載荷46~1500字節(jié)真正的數(shù)據(jù)內(nèi)容通常是一個(gè)IP數(shù)據(jù)報(bào)FCS幀校驗(yàn)序列4字節(jié)對整個(gè)幀體做CRC校驗(yàn)得到的校驗(yàn)碼前導(dǎo)碼很多人容易忽略它不算正式幀的一部分但非常關(guān)鍵。它是一串固定的101010...序列最后兩位是11接收方的網(wǎng)卡靠它來鎖定比特同步時(shí)鐘。這就是為什么你說“物理層把比特流送來了”接收方卻必須靠前導(dǎo)碼才能知道“從哪一位開始算一個(gè)字節(jié)”。有個(gè)典型的理解誤區(qū)總有人問“既然數(shù)據(jù)載荷寫的是46~1500字節(jié)那我傳一個(gè)很小的數(shù)據(jù)不足46字節(jié)怎么辦”答案是填充。發(fā)送方會在載荷不夠長度時(shí)填充一些字節(jié)讓幀長湊夠64字節(jié)的最小值。為什么非要至少64字節(jié)這跟3.2節(jié)要講的CSMA/CD沖突檢測機(jī)制強(qiáng)相關(guān)先記住結(jié)論后面展開。2.2 CRC校驗(yàn)手把手手算一遍CRC是循環(huán)冗余校驗(yàn)的縮寫也是這章最容易讓人一知半解的點(diǎn)。很多教材喜歡直接給“多項(xiàng)式除法”的概念把初學(xué)者嚇退。其實(shí)說人話就是發(fā)送方利用一個(gè)生成多項(xiàng)式對數(shù)據(jù)做一個(gè)二進(jìn)制除法得到的余數(shù)就是FCS附在數(shù)據(jù)后面一起發(fā)出去。接收方拿著整個(gè)幀再做一次同樣的除法如果余數(shù)是0說明沒有檢測到錯誤如果不是0幀就是錯的。我建議你親手算一遍比看任何公式都管用。假設(shè)我們要發(fā)送的數(shù)據(jù)M是10位1010001101生成多項(xiàng)式是P110101對應(yīng)x^5x^4x^21。計(jì)算流程是先在數(shù)據(jù)M后面補(bǔ)5個(gè)0因?yàn)樯啥囗?xiàng)式是6位、最高次是5余數(shù)就是5位然后做模2除法也就是按位異或不借位不進(jìn)位。我把除法的關(guān)鍵過程寫出來被除數(shù)101000110100000 除數(shù) 110101 第1步從最高位開始101000對110101做異或首位1夠除 101000 ^ 110101 011101 第2步把下一格0拉下來變成111010首位1繼續(xù)異或 111010 ^ 110101 001111 第3步繼續(xù)把后面的0拉下來變成011110此時(shí)首位是0不夠除商0 第4步再拉一個(gè)0下來變成111100首位是1異或 111100 ^ 110101 001001 第5步再拉0下來變成010010首位0商0 第6步再拉0下來變成100100首位1異或 100100 ^ 110101 010001 第7步最后再拉一個(gè)0下來變成100010首位1異或 100010 ^ 110101 010111 余數(shù)010111我這里稍微簡化了過程實(shí)際手算時(shí)記得每一位都要拉到底、對齊處理。計(jì)算出來的余數(shù)R010111這5位就是FCS。發(fā)送方真正發(fā)出去的幀數(shù)據(jù)是原數(shù)據(jù)1010001101 FCS 010111合起來是1010001101010111。接收方拿到這14位后用同樣的生成多項(xiàng)式110101再做一次模2除法如果余數(shù)為0就判定正確。我第一次手算CRC時(shí)犯了一個(gè)典型錯誤補(bǔ)零的個(gè)數(shù)搞錯了。補(bǔ)零的個(gè)數(shù)不是“生成多項(xiàng)式的位數(shù)減一”而是“生成多項(xiàng)式最高次方”那么多位例如P110101最高次是5所以補(bǔ)5個(gè)0。這個(gè)細(xì)節(jié)很容易錯做題時(shí)務(wù)必先寫清楚生成多項(xiàng)式的階數(shù)。2.3 關(guān)于“可靠傳輸”這點(diǎn)千萬別理解偏了數(shù)據(jù)鏈路層的差錯檢測只能“檢錯”不能“糾錯”。收到一個(gè)FCS校驗(yàn)失敗的幀接收方的做法很簡單直接丟棄不做任何通知。至于丟掉的幀怎么辦那是上層協(xié)議的事通常是TCP的確認(rèn)重傳機(jī)制來負(fù)責(zé)。這一點(diǎn)讓很多人困惑既然數(shù)據(jù)鏈路層能算出FCS為什么不對錯誤幀進(jìn)行修復(fù)原因是修復(fù)的成本遠(yuǎn)高于重傳。CRC只能告訴你“這幀不對”但不能告訴你“是哪幾位被改錯了”。想糾錯就得用海明碼那樣的編碼方式會大幅增加冗余數(shù)據(jù)對高速以太網(wǎng)來說代價(jià)太大。網(wǎng)絡(luò)通信的設(shè)計(jì)哲學(xué)是“把可靠性的問題交給專業(yè)層解決”鏈路層保證“盡量不傳錯”并快速丟棄錯誤幀由傳輸層統(tǒng)一把關(guān)。我在實(shí)際分析抓包數(shù)據(jù)時(shí)發(fā)現(xiàn)一個(gè)特別有意思的現(xiàn)象有時(shí)抓包里能看到“TCP retransmission”的提示但對應(yīng)的鏈路幀F(xiàn)CS并沒有報(bào)錯。這說明數(shù)據(jù)是在中間某條鏈路上丟的根本傳不到接收端而發(fā)送端只能靠TCP超時(shí)重傳發(fā)現(xiàn)。鏈路層重傳在以太網(wǎng)這種高可靠的介質(zhì)上收益不大但在無線局域網(wǎng)802.11里由于信道環(huán)境差鏈路層就加了確認(rèn)幀的重傳機(jī)制。學(xué)到這里你就能明白為什么同是“鏈路層”有線無線差別這么大——因?yàn)榻橘|(zhì)的可靠性完全不一樣。3. CSMA/CD、MAC地址與交換機(jī)弄懂它們物理層知識才算真正貫通3.1 CSMA/CD是如何解決“多人共用一條路”的早期以太網(wǎng)是總線型的一根同軸電纜上掛了很多臺電腦大家共用一條信道。這就好比一個(gè)房間只有一部電話但住了十個(gè)人所有人同時(shí)想打電話就會互相打斷。CSMA/CD協(xié)議就是一套“先聽后說、邊說邊聽”的規(guī)則全稱是載波監(jiān)聽多路訪問/碰撞檢測。規(guī)則分幾步理解很清楚第一步發(fā)送方發(fā)送前先監(jiān)聽信道信道空閑才發(fā)忙就等第二步發(fā)送過程中要同時(shí)監(jiān)聽如果檢測到信號幅度異常、說明有碰撞立即停止發(fā)送第三步停下來后發(fā)送一個(gè)強(qiáng)化沖突信號告訴所有人“剛才撞車了”第四步采用二進(jìn)制指數(shù)退避算法隨機(jī)等一段時(shí)間再重試。你可能會問為什么要“邊說邊聽”因?yàn)樵诳偩€拓?fù)淅镄盘枏囊欢藗鞯搅硪欢耸怯醒舆t的發(fā)送方發(fā)出第一個(gè)比特后的短時(shí)間內(nèi)其他設(shè)備可能還沒收到信號如果它們這時(shí)也發(fā)數(shù)據(jù)就會撞車。碰撞是有窗口期的這個(gè)窗口期就是信號在總線上來回傳播的最長時(shí)間叫沖突窗口數(shù)值上等于2倍的單程傳播時(shí)延。這里引出那個(gè)經(jīng)典的“最小幀長”計(jì)算。以太網(wǎng)的沖突窗口大約是51.2微秒在10Mbps的速率下發(fā)送255位只需要25.5微秒但如果發(fā)送方發(fā)出的幀太短可能在它檢測到碰撞之前整幀就已經(jīng)發(fā)完了——它根本不知道自己“撞了”。為了讓發(fā)送方在發(fā)送過程中能感知到碰撞必須讓一個(gè)幀的發(fā)送時(shí)間大于等于沖突窗口。算一下10Mbps × 51.2微秒 512比特正好64字節(jié)。這就是以太網(wǎng)最小幀長64字節(jié)的來歷。所有小于64字節(jié)的幀都被認(rèn)為是“沖突碎片”直接丟棄。還需要知道的是隨著以太網(wǎng)交換機(jī)的普及現(xiàn)在的全雙工鏈路已經(jīng)不需要CSMA/CD了因?yàn)榻粨Q機(jī)的每個(gè)端口和主機(jī)之間是獨(dú)立鏈路不存在共享信道競爭問題。但學(xué)這個(gè)協(xié)議的價(jià)值依然很大它教會你一套理解“共享介質(zhì)訪問控制”的思維模型后面學(xué)習(xí)無線局域網(wǎng)的CSMA/CA時(shí)你會覺得似曾相識。3.2 MAC地址與IP地址的分工很多人初學(xué)時(shí)搞不清一個(gè)問題既然每個(gè)設(shè)備都有IP地址為什么數(shù)據(jù)鏈路層還要搞一個(gè)MAC地址我的理解方式是做一個(gè)類比IP地址是“門牌號”MAC地址是“門牌編號對應(yīng)的那塊門牌本身”。門牌號可以因?yàn)榘峒叶淖兊W(wǎng)卡上的MAC地址在出廠時(shí)通常固化了。MAC地址是數(shù)據(jù)鏈路層使用的物理地址長度為6字節(jié)前3字節(jié)是廠商編號OUI后3字節(jié)是網(wǎng)卡序列號。它解決的是“在同一個(gè)物理鏈路內(nèi)幀該送給誰”的問題。而IP地址是網(wǎng)絡(luò)層的邏輯地址解決的是“在互聯(lián)網(wǎng)這個(gè)巨大網(wǎng)絡(luò)中數(shù)據(jù)報(bào)該發(fā)往哪個(gè)目的網(wǎng)絡(luò)”的問題。一個(gè)包要從一臺電腦發(fā)到另一臺城市的電腦中間跨越很多條鏈路在每一條鏈路上數(shù)據(jù)幀的源MAC和目的MAC是隨路由器轉(zhuǎn)發(fā)而變化的但I(xiàn)P數(shù)據(jù)報(bào)里的源IP和目的IP在一整段旅程中保持不變。這就是“MAC地址逐跳變化、IP地址端到端不變”的規(guī)律。把這兩個(gè)地址搞混的人會在配置網(wǎng)絡(luò)時(shí)出各種奇怪的問題。比如我做實(shí)驗(yàn)時(shí)曾經(jīng)手動改了網(wǎng)卡的“本地連接”里的MAC地址結(jié)果同一局域網(wǎng)內(nèi)能通信但出外網(wǎng)就斷了——因?yàn)槁酚善魃辖壎嗽璏AC地址的ARP表項(xiàng)這就是MAC層和IP層交織的典型案例。3.3 交換機(jī)是怎么“自學(xué)成才”的交換機(jī)是數(shù)據(jù)鏈路層的核心設(shè)備它的“聰明”之處在于不需要人工配置路由而是通過不斷學(xué)習(xí)幀中的源MAC地址建立一張MAC地址表。我常在課上強(qiáng)調(diào)交換機(jī)轉(zhuǎn)發(fā)幀的依據(jù)就是這張MAC地址表記錄的是“哪個(gè)MAC地址出現(xiàn)在哪個(gè)端口”。具體過程可以分三種情況說明第一種目的MAC地址在表中存在并且對應(yīng)端口就是幀進(jìn)入的端口那交換機(jī)就把幀“丟棄”了因?yàn)樵谕粋€(gè)端口內(nèi)兩個(gè)設(shè)備通信沒必要在交換機(jī)內(nèi)部轉(zhuǎn)發(fā)第二種目的MAC地址在表中存在且對應(yīng)端口不是入口就只往那個(gè)端口轉(zhuǎn)發(fā)第三種目的MAC地址不在表中也就是“未知單播”交換機(jī)就向除了入口之外的所有端口泛洪。通過學(xué)習(xí)交換機(jī)不需要人為設(shè)置轉(zhuǎn)發(fā)表插上設(shè)備就能自動構(gòu)建。我做過一個(gè)小實(shí)驗(yàn)用兩臺電腦接同一個(gè)交換機(jī)先互相ping一次然后在交換機(jī)上和電腦上分別查MAC地址表會發(fā)現(xiàn)電腦A的MAC地址出現(xiàn)在交換機(jī)連接電腦A的那個(gè)端口下。這就是交換機(jī)在學(xué)習(xí)過程最直觀的證據(jù)。交換機(jī)的引入改變了“沖突域”的概念。傳統(tǒng)集線器下所有端口共用一個(gè)沖突域任意兩臺設(shè)備同時(shí)發(fā)送都會碰撞而交換機(jī)的每個(gè)端口都對應(yīng)一個(gè)獨(dú)立的沖突域全雙工模式下甚至沒有沖突。但要注意交換機(jī)的所有端口仍然在一個(gè)廣播域里廣播幀會轉(zhuǎn)發(fā)到所有端口。這也是“沖突域被交換機(jī)隔離廣播域沒有被隔離”這句口訣的出處。4. 動手驗(yàn)證與排錯抓包、算碼、拆包4.1 用抓包軟件看真實(shí)以太網(wǎng)幀學(xué)數(shù)據(jù)鏈路層最忌諱只看書不動手我強(qiáng)烈建議你打開Wireshark親手抓一個(gè)真實(shí)的以太網(wǎng)幀。操作不復(fù)雜找一臺電腦打開Wireshark選一個(gè)正在通信的網(wǎng)卡比如已經(jīng)聯(lián)網(wǎng)的無線網(wǎng)卡或有線網(wǎng)卡設(shè)置過濾器為“arp”或“ip”然后去ping同網(wǎng)段的另一臺設(shè)備比如網(wǎng)關(guān)等抓到包后展開Ethernet II那一段就能看到真實(shí)的幀頭目的MAC、源MAC、Type字段??催@個(gè)幀頭時(shí)你會發(fā)現(xiàn)自己對幀結(jié)構(gòu)的理解立刻具象化了。我建議重點(diǎn)看三個(gè)信息一是Type值0x0800表明上一層是IPv40x0806表明是ARP二是目的MAC如果它是ff:ff:ff:ff:ff:ff這樣的全F地址說明這是一個(gè)廣播幀三是源MAC和你在命令行里用ipconfig /all或ifconfig查到的網(wǎng)卡物理地址是否一致。很多人在這一步才發(fā)現(xiàn)實(shí)際抓包看到的幀頭和課本上畫的示意圖幾乎沒有差別。觀察時(shí)要注意一個(gè)坑如果用無線網(wǎng)卡抓自己的ping包可能看到源MAC不是本機(jī)網(wǎng)卡的MAC而是路由器或AP的MAC。原因是無線網(wǎng)卡在接入無線網(wǎng)絡(luò)后很多驅(qū)動默認(rèn)開啟了“無線擴(kuò)展”模式部分抓包軟件會看到AP轉(zhuǎn)發(fā)的數(shù)據(jù)。遇到這種情況不用慌說明你的數(shù)據(jù)確實(shí)經(jīng)過了無線鏈路的中繼換一個(gè)有線網(wǎng)卡抓包會更干凈。4.2 寫一段代碼對照CRC計(jì)算結(jié)果光手算一遍還不夠我建議你再用代碼快速驗(yàn)證一下把前面2.2節(jié)的例子跑通。CRC的代碼其實(shí)不難核心就是模擬模2除法。我用Python寫過一段最簡單的實(shí)現(xiàn)def crc_remainder(data: str, generator: str) - str: # 在數(shù)據(jù)末尾補(bǔ) (生成多項(xiàng)式位數(shù) - 1) 個(gè)0 g_len len(generator) dividend data 0 * (g_len - 1) dividend list(dividend) generator_bits list(generator) for i in range(len(data)): if dividend[i] 1: for j in range(g_len): dividend[i j] str( int(dividend[i j]) ^ int(generator_bits[j]) ) return .join(dividend[-(g_len - 1):])用前面例子跑一下data 1010001101 generator 110101 remainder crc_remainder(data, generator) print(remainder) # 和手算結(jié)果 010111 一致接收端校驗(yàn)就更簡單了把“數(shù)據(jù) 余數(shù)”整體作為輸入再調(diào)用這個(gè)函數(shù)得到的余數(shù)如果是全0就說明校驗(yàn)通過。我第一次寫這段代碼的時(shí)候犯了個(gè)低級錯誤循環(huán)范圍用的是len(dividend)把FCS后面的部分也算進(jìn)去了結(jié)果校驗(yàn)結(jié)果一直是錯的。正確做法是只對原始數(shù)據(jù)位做消位操作因?yàn)镕CS本身只是“除法的余數(shù)”不需要再拿來參與消位。這個(gè)細(xì)節(jié)自己寫一遍代碼就能記住。4.3 初學(xué)者最容易踩的三個(gè)認(rèn)知坑這一章里我踩過不少坑也幫別人排查過不少網(wǎng)絡(luò)問題總結(jié)出三個(gè)高頻誤區(qū)。第一個(gè)誤區(qū)是把“沖突域”和“廣播域”當(dāng)成同一個(gè)概念。我剛學(xué)完時(shí)也這么以為后來做了個(gè)小實(shí)驗(yàn)才徹底區(qū)分開用一臺交換機(jī)連接三臺電腦其中一臺發(fā)廣播包另外兩臺都能收到說明整個(gè)交換機(jī)組在一個(gè)廣播域里但兩臺電腦互相傳大文件時(shí)第三臺電腦的網(wǎng)速幾乎不受影響說明它們不在一個(gè)沖突域。簡單說沖突域是“物理上可能發(fā)生碰撞的范圍”廣播域是“邏輯上廣播能到達(dá)的范圍”。第二個(gè)誤區(qū)是“以為CRC能夠糾正錯誤”。這個(gè)想法很誘人實(shí)際上鏈路層FCS只能檢錯不能告訴你是哪一位錯了。網(wǎng)絡(luò)中為了糾錯付出的額外帶寬成本很高鏈路層選擇“檢錯并丟棄”可靠傳輸交給上層。理解這個(gè)設(shè)計(jì)哲學(xué)之后看很多網(wǎng)絡(luò)協(xié)議的設(shè)計(jì)取舍都會更有感覺。第三個(gè)誤區(qū)是“把FCS的作用范圍搞錯”。FCS校驗(yàn)的對象是整個(gè)幀從目的MAC開始一直到數(shù)據(jù)載荷的部分不包括前導(dǎo)碼。有人抓包時(shí)發(fā)現(xiàn)幀數(shù)據(jù)內(nèi)容改動但FCS沒變就懷疑校驗(yàn)算法有誤實(shí)際上是抓包工具會自動重新計(jì)算FCS原始線路上的FCS已經(jīng)被網(wǎng)卡剝離或更新了。排查問題時(shí)可別被這個(gè)現(xiàn)象帶偏。我在實(shí)際排查中還有一個(gè)小技巧當(dāng)懷疑是鏈路層問題導(dǎo)致丟包時(shí)優(yōu)先看交換機(jī)的端口統(tǒng)計(jì)里的CRC錯誤計(jì)數(shù)如果這個(gè)數(shù)字在持續(xù)增長大概率是網(wǎng)線質(zhì)量差、接觸不良或者端口雙工模式不匹配。這個(gè)排查方向比反復(fù)ping、traceroute高效得多。很多人遇到丟包第一時(shí)間就去查網(wǎng)絡(luò)層忘了看看鏈路層的物理錯誤計(jì)數(shù)器這是我們做網(wǎng)絡(luò)排障時(shí)最常忽略、卻也最有效的一步。這套筆記我前后整理了好幾輪最大的心得體會是學(xué)習(xí)數(shù)據(jù)鏈路層一定不能只停留在背概念動手抓一次包、親手算一遍CRC、用交換機(jī)做一次轉(zhuǎn)發(fā)實(shí)驗(yàn)勝過看十遍教材。如果你正在學(xué)這章建議先別急著往后翻花一晚上把幀結(jié)構(gòu)、CRC、CSMA/CD、交換機(jī)這幾件事對著實(shí)驗(yàn)捋一遍你會發(fā)現(xiàn)后面學(xué)網(wǎng)絡(luò)層時(shí)很多“路由器怎么轉(zhuǎn)發(fā)”“ARP怎么工作”的問題都會變得順理成章。本篇文章就是我在這一階段最想留給自己的那份操作手冊也是我想分享給同樣卡在這里的朋友的一份避坑指南。