前文相關:
前面學習了第一層,我們知道了物理層的大致作用,瞭解了用線纜構建一個網絡,並知曉了相關設備。
那麼如何從一臺設備向另一臺設備發消息?
要達到這個目的,光靠第一層的硬件顯然是不夠的。
OSI第二層的作用
作爲大名鼎鼎的“數據鏈路層”,其作用有:使局域網中機器相互連接,偵測傳輸錯誤 。他還有個著名的“跟班”:交換機(也就是常說的Switch)
注意,這裏說的是“偵測”,而不是“修正”。
MAC地址——唯一標識
目前網絡上的情況稍有複雜:雖然有時我們想和所有機器通信(好比現實世界中對着大家說話),但是大部分時候,我們每次都是與單獨的一臺機器通信。
那麼,“茫茫機海中,我與誰相逢 ?” …
爲了定位某臺機器,就需要給每臺機器一個:“身份證”了。網絡的先驅們於是在OSI的第二層創建了一個標識,用於標明每一臺機器“是誰”,這個標識被稱爲 MAC地址。
但其實,並不是每一臺機器都有一個(獨立的)MAC地址作爲標識。
大家想啊,既然我們處於OSI第二層,離第一層只有“咫尺之距”,因此MAC地址是和硬件設備有關的 —— 網卡。
網卡上最令我印象深刻的就是連着的RJ45接口(母頭)。
可以說,MAC地址其實是網卡的地址,而不是每臺機器的地址。因此,MAC地址用於在網絡中唯一標識一個網卡,一個電腦會有一個或多個網卡,每個網卡都有自己的MAC地址。
MAC地址的概念
說起來,我們還要找“二進制”好好聊聊!
之前筆者提到過,在信息技術領域,我們用0和1來代表電信號的高電平和低電平,或說兩種狀態(開/關)。
計算機中的許多元件都可以達到這兩種狀態,分別用0和1表示,用來計算或存儲數據。
例如半導體通電錶示1,不通電錶示0,CPU等半導體芯片就是這樣計算的。這樣運算 的有點便是 統一標識、規則簡單、節省設備。
MAC地址以十六進制編碼
十六進制想必也不用多說,由0-9、A-F共同構成的字碼。
而MAC通常表示形式如下: 00:0c:29:10:5a:55
MAC地址編碼
如上表示,MAC地址以6個字節編碼(48個二進制位),每兩個字節由冒號隔開。
一個字節(Byte)是指明一定量的數據的信息元。例如:一個500GB的硬盤,其實就是500個G的Byte的容量。G是英語giga的意思,表示千兆,即十億,10的9次方。因此500GB就有大約500000000000個字節。
爲什麼說“大約”?
精確來看,1GB=1024MB=1024X1024KB=1024X1024X1024B,而硬盤廠商設計時按1GB=1000MB近似計算。
但是現在有個問題,我們如何保證每一塊網卡的MAC地址不會和世界上已經存在的網卡地址重複呢?難道不會搞錯嗎?
一般來說不必考慮此問題。因爲一個網卡製造商會購買MAC地址,更確切地說是MAC地址的區塊。
MAC地址最前面三個字節是IEEE分配的,後面三個字節由製造商自行分配。這樣的話,只要生產商保證自己生產的每塊網卡後面使用不同的三個字節,就不會有重複MAC地址了。
特殊的MAC地址
在衆多的MAC地址中,有一個地址很特殊——其每一個二進制位都是1: ff:ff:ff:ff:ff:ff
它被稱爲 廣播地址 。
廣播,廣而播之。顧名思義,廣播地址可以代表任意一個網卡,因此發向廣播地址的信息就會發送到所在網絡的所有網卡上。
好了,現在我們既已知曉如何用OSI第一層將機器連起來,並用第二層來標識每一臺機器(的網卡)。那麼是時候定義一個互通所需的語言了。
鏈路層的語言——以太網協議
它規定了機器之間交換信息的格式。
在網絡中,我們通常將通信所用的語言成爲“協議”。
在第二層衆多的協議中,我們“一眼看中了” Ethernet,即以太網 。 以太網協議並不是第二層中唯一的協議,但卻是最常用的。
協議的作用
網絡是爲了交換信息而生的,網絡中傳輸的都是0/1這樣的二進制數據。因此,我們極有可能收到如下信息:
0110101110110101100011001
但是就輪到我們懵逼了。這什麼鬼…
協議就是被用來定義用什麼樣的信息、以什麼樣的順序傳輸。
在傳輸的信息裏,要包含:
- 發送方地址
- 接收方地址
- 信息的實際內容
這樣的一個信息單元的總,術語稱之爲 幀 (數據幀)。幀是OSI第二層中傳輸的數據單元,可以將其看做數據包。
以太網中幀的形式
現在有一個問題:在一個幀中,到底是發送方的MAC地址在前還是接收方的在前?
爲了回答這個問題,我們需要換位思考,想象自己就是那臺接收信息的機器。
對於機器來說,發送方的 MAC 地址和接收方的 MAC 地址,哪一個更有價值呢?
網絡的先驅者們認爲接收方的 MAC 地址對一臺機器來說更有價值,因爲可以立即得知信息是不是發給我們的。如果信息是發給我們的,那麼我們閱讀信息;如果不是發給我們的,那麼大可不必理會。
因此我們在一個幀中,將接收方的 MAC 地址(也叫 MAC 目標地址)放在前,後面跟着發送方的 MAC 地址(也叫 MAC 源地址)。目前我們的以太網幀大致如下:
我們知道,OSI七層模型在發送發發送信息時,需要從上到下依次穿過OSI各層:
就是說,在穿越第 2 層前,我們需要穿越第 3 層,這樣,第 3 層就可以告訴第 2 層在第 3 層使用的協議是什麼了。
這很有用,因爲當信息到達接收方的時侯,接收方的機器的第 2 層首先檢驗 MAC 目標地址,如果和自己的 MAC 地址一樣,那麼接收方的機器的第 2 層需要將信息發送到第 3 層的對應協議。
在接收方,需要反向穿越 OSI,如下圖所示:
至此,我們的以太網幀變成了這樣:
還沒完!
和一個完整的幀段相比,還缺了:
- 要發送的信息本身
- 錯誤檢測
我們應該將這兩個信息放在第3層時候用的協議後面。
不少人應該會對“錯誤檢測”感興趣:CRC
什麼是CRC ?
CRC 是循環冗餘校驗(Cyclic Redundancy Check)的縮寫,這名字也比較抽象。
CRC 是一個數學的值,可以作爲要發送的數據的一種代表。
簡單說來,CRC 對於每條發送的信息都是不一樣的。發送方使用某公式計算出被傳送數據所含信息的一個 CRC 值,並將此值附在被傳送數據後,接收方則對接收到的同一數據進行相同的計算,得到另一個 CRC 值。
如果這兩個 CRC 一致,說明發送中沒有出錯;如果不一致,說明發送中出現了差錯,接收方可要求發送方重新發送該數據。
假設機器 A 發送一條信息給機器 B:
- 發送前,機器 A 根據發送的信息,來計算 CRC 值(假設值爲 X),將這個值放在一幀的結尾處;
- 機器 B 接收到 機器 A 發送來的一幀數據後,也計算一個 CRC 值(假設值爲 Y);
- 機器 B 比較自己計算出來的 CRC 值(Y)和機器 A 發送過來的幀中的 CRC 值(X);
如果 X 和 Y 相等,說明機器 A 發送的幀和機器 B 收到的幀是一樣的;
如果 X 和 Y 不相等,說明發送時出了問題,機器 A 發送的幀和機器 B 收到的幀不一樣,就成功檢測到了錯誤
現在我們有了完整的元素,那麼我們完整的一幀也就可以“畫出”:
一幀的大小是多少?
在一幀中,有些元素的大小(尺寸)是不變的。這些元素的集合我們稱之爲幀頭。下圖中的粗體表示幀頭裏的數據:
幀頭的格式是固定的,因此我們可以定義其大小:
接收方和發送方的 MAC 地址分別佔用 6 個字節;
第 3 層的協議用 2 個字節編碼;
CRC 用 4 個字節編碼。
6 x 2 + 2 + 4 = 18。
因此以太網的幀頭一共有 18 個字節。
當然,也有一種分法是將一幀分爲幀頭、數據部分、幀尾三部分。接收方和發送方的 MAC 地址和第 3 層使用的協議作爲幀頭,而 CRC 作爲幀尾。
當然了,一幀是有最小尺寸和最大尺寸的 —— 以太網幀的最小尺寸是64字節,最大尺寸是1518字節。
小結:在機器 A 和機器 B 之間交換數據的過程如下:
- 機器 A 上的一個應用(application,在 OSI 的第 7 層應用層,以後我們會學習應用層)想要發送數據到機器 B 的應用上;
- 在 機器 A 這個發送方這端,此數據從上到下穿過 OSI 的各層;
- 到底3層了,發送方的第 3 層去告知第 2 層所使用的協議是什麼;
- 第 2 層用這些信息,包裝成一個幀,通過網絡傳輸;
- 機器 B 收到了機器 A 發送的這個幀,首先檢查幀頭部的第一個元素:接收方的 MAC 地址;
- 如果等於機器 B 的 MAC 地址,那麼機器 B 讀取幀中接下來的信息;
- 依據幀中的協議部分,接收方(機器 B)的第 2 層就把數據正確地發送給第 3 層;
- 數據在接收方就從下到上,直達機器 B 的應用了。