ping 使用 ICMP 協議, ICMP 工作在 IP層所以無端口號, 當多個進程使用ICMP 的時候, 怎么判斷該 ICMP Message 屬于哪個進程?

不像其他應用層的協議如http, 直接監控80端口, ping 若直接使用 ICMP, 那它怎么知道來的數據包就是屬于它的呢?

負責接收處理Ping報文(ICMP Echo

Request)的進程是唯一(Unique)的,且是一個系統進程,所以壓根不會有那么多的煩惱。

這個系統進程,位于TCP/IP協議棧的IP棧,所以一旦IP棧發現這是發給自己的(目的IP == self,且protocol number == 1),直接就把這個Ping報文扔給這唯一的進程處理。

可能與讀者想象的不一樣,Ping 1.1.1.1報文的接收方,處理起來特別簡單,只要把收到的Ping報文幾乎原始模樣反彈(Echo Reply)回去即可。

幾乎的意思是,主機=1.1.1.1 需要做幾個簡單操作:

  • ICMP type =0 修改為8
  • 重新計算ICMP checksum
  • 將原始報文的Source IP(你的IP)、Destination IP (1.1.1.1)對調
  • TTL重置為本地設置
  • 重新計算IP checksum

做完以上操作,即可委托IP路由將Ping

Echo Reply報文發出。畢竟echo的原始意義就是反彈、回音的意思,簡單哇?

同學們可能注意到ICMP報文頭的“Identifier”、“Sequence Number”,接收方壓根沒有觸碰。既然接收方根本不處理,為何還要畫蛇添足呢?

因為 “Identifier” + “Sequence Number” 這個黃金搭檔,不是給接收方用的,而是給發送方(題主)用的。準確地說,是當Ping報文的返回報文(Echo Request),題主主機的操作系統將根據“Identifier”定位是哪個用戶進程的報文,然后把這個報文deliver給對應進程。該進程再根據“Sequence Number”匹配本地發出的Echo Request的“Sequence Number”。如果匹配成功,將該“Sequence Number”對應的定時器熄滅,計算往返時間Round Trip Time,并時間統計打印到屏幕上。

如果在定時器響之前,沒有匹配的echo reply,Ping的統計為失敗, timeout默認 = 2秒。

定時器響了之后,如果收到了對應的“Sequence Number” 的echo reply,直接丟棄處理,因為已經沒有任何意義了。

通常“Identifier”為用戶進程號,這樣處理起來直觀便利。如果不是直接映射,題主的主機有方法根據Identifier的值,找到對應的用戶進程前來處理。總之一句話,不能造成混淆或者無法找到合適的進程處理的現象,這就是協議存在的意義!