當你「ping 一下」的時候,你知道它背後的邏輯嗎?

咱們在遇到網絡不通的狀況,你們都知道去 ping 一下,看一下網絡情況。
那你知道「ping」命令後背的邏輯是什麼嗎?知道它是如何實現的嗎?微信

1、「ping」命令的做用和原理?

簡單來講,「ping」是用來探測本機與網絡中另外一主機之間是否可達的命令,若是兩臺主機之間ping不通,則代表這兩臺主機不能創建起鏈接。ping是定位網絡通不通的一個重要手段。網絡

ping 命令是基於 ICMP 協議來工做的,「 ICMP 」全稱爲 Internet 控制報文協議( Internet Control Message Protocol)。ping 命令會發送一份ICMP回顯請求報文給目標主機,並等待目標主機返回ICMP回顯應答。由於ICMP協議會要求目標主機在收到消息以後,必須返回ICMP應答消息給源主機,若是源主機在必定時間內收到了目標主機的應答,則代表兩臺主機之間網絡是可達的。架構

舉一個例子來描述「ping」命令的工做過程:工具

  1. 假設有兩個主機,主機A(192.168.0.1)和主機B(192.168.0.2),如今咱們要監測主機A和主機B之間網絡是否可達,那麼咱們在主機A上輸入命令:ping 192.168.0.2大數據

  2. 此時,ping命令會在主機A上構建一個 ICMP的請求數據包(數據包裏的內容後面再詳述),而後 ICMP協議會將這個數據包以及目標IP(192.168.0.2)等信息一同交給IP層協議。spa

  3. IP層協議獲得這些信息後,將源地址(即本機IP)、目標地址(即目標IP:192.168.0.2)、再加上一些其它的控制信息,構建成一個IP數據包。事件

  4. IP數據包構建完成後,還不夠,還須要加上MAC地址,所以,還須要經過ARP映射表找出目標IP所對應的MAC地址。當拿到了目標主機的MAC地址和本機MAC後,一併交給數據鏈路層,組裝成一個數據幀,依據以太網的介質訪問規則,將它們傳送出出去。ci

  5. 當主機B收到這個數據幀以後,會首先檢查它的目標MAC地址是否是本機,若是是就接收下來處理,接收以後會檢查這個數據幀,將數據幀中的IP數據包取出來,交給本機的IP層協議,而後IP層協議檢查完以後,再將ICMP數據包取出來交給ICMP協議處理,當這一步也處理完成以後,就會構建一個ICMP應答數據包,回發給主機A路由

  6. 在必定的時間內,若是主機A收到了應答包,則說明它與主機B之間網絡可達,若是沒有收到,則說明網絡不可達。除了監測是否可達之外,還能夠利用應答時間和發起時間之間的差值,計算出數據包的延遲耗時。it

經過ping的流程能夠發現,ICMP協議是這個過程的基礎,是很是重要的,所以下面就把ICMP協議再詳細解釋一下。

2、什麼是「 ICMP 」?

咱們知道,ping命令是基於ICMP協議來實現的。那麼咱們再來看下圖,就明白了ICMP協議又是經過IP協議來發送的,即ICMP報文是封裝在IP包中。

IP協議是一種無鏈接的,不可靠的數據包協議,它並不能保證數據必定被送達,那麼咱們要保證數據送到就須要經過其它模塊來協助實現,這裏就引入的是ICMP協議。

當傳送的IP數據包發送異常的時候,ICMP就會將異常信息封裝在包內,而後回傳給源主機。

將上圖再細拆一下可見:

繼續將ICMP協議模塊細拆:

由圖可知,ICMP數據包由8bit的類型字段和8bit的代碼字段以及16bit的校驗字段再加上選項數據組成。

ICMP協議大體可分爲兩類:

  • 查詢報文類型

  • 差錯報文類型

  1. 查詢報文類型

查詢報文主要應用於:ping查詢、子網掩碼查詢、時間戳查詢等等。

上面講到的ping命令的流程其實就對應ICMP協議查詢報文類型的一種使用。在主機A構建ICMP請求數據包的時候,其ICMP的類型字段中使用的是 8 (回送請求),當主機B構建ICMP應答包的時候,其ICMP類型字段就使用的是 0 (回送應答),更多類型值參考上表。

對 查詢報文類型 的理解可參考一下文章最開始講的ping流程,這裏就不作贅述。

  1. 差錯報文類型

差錯報文主要產生於當數據傳送發送錯誤的時候。
它包括:目標不可達(網絡不可達、主機不可達、協議不可達、端口不可達、禁止分片等)、超時、參數問題、重定向(網絡重定向、主機重定向等)等等。

差錯報文一般包含了引發錯誤的IP數據包的第一個分片的IP首部,加上該分片數據部分的前8個字節。
當傳送IP數據包發生錯誤的時候(例如 主機不可達),ICMP協議就會把錯誤信息封包,而後傳送回源主機,那麼源主機就知道該怎麼處理了。

那是否是隻有遇到錯誤的時候才能使用 差錯報文類型 呢?也不必定。

Traceroute 就是一個例外,Traceroute是用來偵測源主機到目標主機之間所通過路由狀況的經常使用工具。Traceroute 的原理就是利用ICMP的規則,製造一些錯誤的事件出來,而後根據錯誤的事件來評估網絡路由狀況。

具體作法就是:

Traceroute會設置特殊的TTL值,來追蹤源主機和目標主機之間的路由數。首先它給目標主機發送一個 TTL=1 的UDP數據包,那麼這個數據包一旦在路上遇到一個路由器,TTL就變成了0(TTL規則是每通過一個路由器都會減1),由於TTL=0了,因此路由器就會把這個數據包丟掉,而後產生一個錯誤類型(超時)的ICMP數據包回發給源主機,也就是差錯包。這個時候源主機就拿到了第一個路由節點的IP和相關信息了。

接着,源主機再給目標主機發一個 TTL=2 的UDP數據包,依舊上述流程走一遍,就知道第二個路由節點的IP和耗時狀況等信息了。

如此反覆進行,Traceroute就能夠拿到從主機A到主機B之間全部路由器的信息了。

可是有個問題是,若是數據包到達了目標主機的話,即便目標主機接收到TTL值爲1的IP數據包,它也是不會丟棄該數據包的,也不會產生一份超時的ICMP回發數據包的,由於數據包已經達到了目的地嘛。那咱們應該怎麼認定數據包是否達到了目標主機呢?

Traceroute的方法是在源主機發送UDP數據包給目標主機的時候,會設置一個不可能達到的目標端口號(例如大於30000的端口號),那麼當這個數據包真的到達目標主機的時候,目標主機發現沒有對應的端口號,所以會產生一份「端口不可達」的錯誤ICMP報文返回給源主機。

可見Traceroute的原理確實很取巧,頗有趣。

以上,就是對ping的基本原理以及ICMP協議的基本講解了,歡迎你們一塊兒交流。

本文原創發佈於微信公衆號「 不止思考 」,歡迎關注,交流Java、Web、架構、大數據、職業發展、技術管理。  

相關文章
相關標籤/搜索