链路层寻址和ARP
一、網絡層地址和鏈路層地址
每個節點有網絡層地址和鏈路層地址。
網絡層地址:節點在網絡中分配的一個唯一地址即IP地址,用于把分組送到目的IP網絡。長度為32比特。
鏈路層地址:又叫做MAC地址或物理地址、局域網地址。此地址用于把數據幀從一個節點傳送到另一個節點中。
MAC地址是節點“網卡”本身所帶的地址,是唯一的。它的地址長度通常為6字節即48比特。這2字節的地址用16進制表示,每個字節表示為一對16進制數。
注意網卡的MAC地址是永久的,它在生產時固化在其ROM里。
下圖為局域網的MAC地址:
局域網中每個網卡都有唯一的局域網地址。
二、MAC地址分配
(1)每個MAC地址都是由專門機構IEEE來管理的。IEEE機構負責分配六個字節中的前三個字節即高24位。如下圖。
(2)MAC地址是平面結構,即帶有同一網卡的節點,在任何網絡中都有同樣的MAC地址。而IP地址具有層次結構,即當節點移動到不同網絡時,節點的IP地址發生改變。
三、MAC地址識別
廣播信道的局域網中,一個節點發送的幀,在信道上廣播傳播,其他節點都可能收到該幀。但是在大多數情況下,一個節點只向某個特定的節點發送。在發送過程中,由“網卡”負責MAC地址的封裝和識別。
(1)發送適配器:將目的MAC地址封裝到幀中,并發送。所有其他適配器都會收到這個幀。
(2)接收適配器:檢查幀的目的MAC地址是否與自己MAC地址相匹配,若匹配則接收該幀,取出數據報并傳遞給上層。若不匹配則丟棄該幀。
這里有一個特殊的廣播幀,即發送給所有節點的幀,需要用廣播地址,廣播地址就是全1地址。
節點的表示除了可以使用應用層主機名、網絡層的IP地址之外也可以使用鏈路層的MAC地址。在實際鏈路傳輸時,根據MAC地址確定相應的節點。下圖位主機的IP地址和MAC地址。
四、地址之間的轉換
在實際的數據發送中,需要目的主機的IP地址和MAC地址。這就需要在地址之間進行轉化。例如已知主機名,利用主機名可以查找對應的IP地址;已知目的主機的IP地址,查找它在局域網中的MAC地址。
(1)DNS域名系統:將主機名解析到IP地址。DNS為在因特網中任何地方的主機解析主機名。
(2)ARP地址解析協議:將IP地址解析到MAC地址。ARP只為在同一個LAN上的節點解析IP地址。
1、ARP地址解析協議
如何根據一個主機的IP地址查找其MAC地址的呢?
局域網上的每個節點都會維護一個ARP表,這個表會記錄當前所知的IP地址到MAC地址的映射信息。如下所示:
TTL存活時間):地址映射將被刪除的時間,通常為20分鐘。即20分鐘后這個映射表項就會被刪除。
2、兩個主機位于同一個局域網內的ARP地址解析過程
假設用一個局域網中主機A希望發送數據報給主機B,主機A首先檢查自己維護的ARP表,看是否存在B的MAC地址。假設B的MAC地址不在A的ARP映射表中。則主機A首先廣播ARP查詢分組,其中包含B的IP地址。查詢分組是個廣播幀,其MAC地址是全F即FF-FF-FF-FF-FF-FF。因此局域網中所有節點都能搜到ARP查詢分組。其余主機發現查詢的不是本機的MAC地址時不會進行回應。只有主機B在收到ARP查詢分組后返回B的MAC地址給主機A即將包含B的MAC地址的幀發送給主機A。主機A在它的ARP表中緩存主機B的IP地址到MAC地址的映射。直到信息超時被刪除或有新的更新消息。
這里要注意ARP是即插即用的也就是說節點創建ARP不需要網絡管理員的干預。
3、兩個主機位于不同局域網的ARP地址解析過程
上述講的是發送方和接收方都處在同一個局域網內,更常見的情況是主機A 需要發送數據報給其它局域網的主機B,這時數據幀的轉發情況是什么呢?
如上圖,主機A經路由器R發送數據報給主機B,假設主機A知道第一跳路由器R的IP地址,這里可以通過DHCP協議獲得。假設主機A也知道路由器R的MAC地址,其可以通過ARP協議獲得。
首先主機A構建IP數據報,源地址是A的IP地址111.111.111.111,目的地址是B的IP地址222.222.222.222。數據報封裝成數據幀的源MAC地址是主機A自己的MAC地址74-29-9C-E8-FF-55。目的MAC地址是路由器左邊端口的MAC地址E6-E9-00-17-BB-4B。如下圖所示。
該數據幀到達路由器R后,路由器R收到數據幀,然后抽取出數據報遞交到IP層。網絡層根據目的IP地址判斷該數據報要發往路由器右邊的端口。且接收主機B與自己右邊的端口屬于同一個局域網。因此向右邊右邊輸出端口輸出數據幀時,數據幀的源MAC地址是路由器右邊端口的MAC地址,目的MAC地址是主機B的MAC地址。
這里注意在整個數據幀的傳送過程中數據報的源IP地址和目的IP地址沒有改變。改變的只是數據幀的源MAC地址和目的MAC地址。
總結
- 上一篇: TCP 中粘包的产生和解决
- 下一篇: 多路 IO 转接 :select 函数