ping 之后,計(jì)算機(jī)背后都做了些了什么
因耗子叔推薦,最近在看《TCP IP 詳解》,里面講到了 ping,今天來(lái)聊聊 ping。如果覺(jué)得有收獲,不妨隨手一個(gè)關(guān)注,每天學(xué)點(diǎn)技術(shù)。
ping 我相信你一定用過(guò),剛裝完電腦,不能上網(wǎng)的時(shí)候,我們就會(huì) ping 一下目標(biāo)機(jī)器,如果 ping 不同,那就說(shuō)明網(wǎng)絡(luò)不可達(dá),如果能 ping 通但還是無(wú)法上網(wǎng),可能是網(wǎng)絡(luò)配置問(wèn)題。可是你是否想過(guò) ping 之后,計(jì)算機(jī)背后都做了些了什么?你可以把它作為面試題來(lái)回答。
ping 的名字源于聲納定位操作。Ping 程序由 MikeMuuss 編寫(xiě),目的是為了測(cè)試另一臺(tái)主機(jī)是否可達(dá)。該程序發(fā)送一份 ICMP 回顯請(qǐng)求報(bào)文給主機(jī),并等待主機(jī)返回 ICMP 應(yīng)答報(bào)文。
一般來(lái)說(shuō),如果不能 Ping 到某臺(tái)主機(jī),那么就不能 Telnet 或者 FTP 到那臺(tái)主機(jī)。反過(guò)來(lái),如果不能 Telnet 到某臺(tái)主機(jī),那么通??梢杂?Ping 程序來(lái)確定問(wèn)題出在哪里。Ping 程序還能測(cè)出到這臺(tái)主機(jī)的往返時(shí)間,以表明該主機(jī)離我們有多遠(yuǎn)。
幾年前我們還可以作出這樣沒(méi)有限定的斷言,如果不能 Ping 到某臺(tái)主機(jī),那么就不能 Telnet 或 FTP 到那臺(tái)主機(jī)。隨著 Internet 安全意識(shí)的增強(qiáng),出現(xiàn)了提供訪問(wèn)控制清單的路由器和防火墻(禁止 ping 的策略),那么像這樣沒(méi)有限定的斷言就不再成立了。一臺(tái)主機(jī)的可達(dá)性可能不只取決于 IP 層是否可達(dá),還取決于使用何種協(xié)議以及端口號(hào)。Ping 程序的運(yùn)行結(jié)果可能顯示某臺(tái)主機(jī)不可達(dá),但我們可以用 Telnet 遠(yuǎn)程登錄到該臺(tái)主機(jī)的 25 號(hào)端口,比如郵件服務(wù)器。
前面提到,ping 使用的是 ICMP 協(xié)議,那要了解下什么是 ICMP,ICMP 是 Internet 控制報(bào)文協(xié)議,位于 TCP/IP 協(xié)議族的的網(wǎng)絡(luò)層:

請(qǐng)注意,雖然 ICMP 和 IP 協(xié)議都在網(wǎng)絡(luò)層,但是 ICMP 在傳輸時(shí)是被封裝在 IP 報(bào)文內(nèi)部的,原因也很簡(jiǎn)單,沒(méi)有 IP 協(xié)議,怎么知道你要把報(bào)文傳給誰(shuí)呢,IP 協(xié)議就相當(dāng)于一個(gè)信封。
也就是說(shuō):

不妨讓大腦牢記一下這個(gè)圖:

現(xiàn)在來(lái)看下 ICMP 報(bào)文的格式:

但是 ICMP 回顯請(qǐng)求和回顯應(yīng)答報(bào)文,又多了一些標(biāo)識(shí)符和序號(hào)兩個(gè)固定字段:

標(biāo)識(shí)符有什么用呢?Unix 系統(tǒng)在實(shí)現(xiàn) ping 程序時(shí)是把 ICMP 報(bào)文中的標(biāo)識(shí)符字段置成發(fā)送進(jìn)程的 ID 號(hào)。這樣即使在同一臺(tái)主機(jī)上同時(shí)運(yùn)行了多個(gè) ping 程序?qū)嵗?,ping 程序也可以識(shí)別出返回的信息。
序號(hào)就很簡(jiǎn)單了,從 0 開(kāi)始,每發(fā)送一次新的回顯請(qǐng)求就加 1。ping 程序打印出返回的每個(gè)分組的序列號(hào),允許我們查看是否有分組丟失、失序或重復(fù)。

從上述 ping 的結(jié)果看,處理序號(hào),還有 ttl 和 time,ttl 就是 time to live,指的是報(bào)文在網(wǎng)絡(luò)中能夠存活的限制,就是當(dāng)報(bào)文在網(wǎng)絡(luò)中轉(zhuǎn)發(fā)時(shí),每經(jīng)過(guò)一個(gè)路由點(diǎn),就把預(yù)先設(shè)定的這個(gè) ttl 數(shù)值減 1,直到最后 ttl=1 時(shí)報(bào)文就被扔掉,不向下轉(zhuǎn)發(fā)。
time 就是往返時(shí)間,ping 程序通過(guò)在 ICMP 報(bào)文數(shù)據(jù)中存放發(fā)送請(qǐng)求的時(shí)間值,當(dāng)應(yīng)答返回時(shí),用當(dāng)前時(shí)間減去存放在 ICMP 報(bào)文中的時(shí)間值,即是往返時(shí)間。
ping 的是域名,但 ping 輸出的第一行包括目的主機(jī)的 IP 地址,說(shuō)明在發(fā)送 ICMP 報(bào)文之前,還請(qǐng)求了 DNS 服務(wù)器。
ping 程序還可以查看訪問(wèn)目標(biāo)地址時(shí)經(jīng)過(guò)了哪些路由,加上 -R 選項(xiàng)就可以:

可以看到有經(jīng)過(guò)了 9 個(gè)路由,不過(guò),ping 最多顯示 9 個(gè)路由 ip,因?yàn)槎嗔朔挪幌?,man 下,看看對(duì) -R 的解釋?zhuān)f(shuō)的就是 ip 的頭部最多放 9 個(gè) ip,如果想查看路由,要用 traceroute 命令。

ping 程序是對(duì)兩個(gè) TCP/IP 系統(tǒng)連通性進(jìn)行測(cè)試的基本工具。它只利用 ICMP 回顯請(qǐng)求和回顯應(yīng)答報(bào)文,而不用經(jīng)過(guò)傳輸層(TCP/UDP)。ping 程序請(qǐng)求主機(jī)時(shí),并不是主機(jī)上的某個(gè)用戶進(jìn)程來(lái)應(yīng)答的,而是操作系統(tǒng)的內(nèi)核,也就是說(shuō)操作系統(tǒng)內(nèi)核層面就實(shí)現(xiàn)了對(duì) ping 程序的響應(yīng)。
最后的話
總結(jié)一下,就是客戶端 ping 之后,如果是域名會(huì)去查 DNS 服務(wù)器找到目標(biāo) ip 地址,然后構(gòu)建 ICMP 報(bào)文,將自己的進(jìn)程 id 寫(xiě)入標(biāo)識(shí)符,將序號(hào)寫(xiě)入序號(hào)字段,發(fā)送時(shí)間寫(xiě)入數(shù)據(jù)字段,將目標(biāo) ip 寫(xiě)入 IP 報(bào)文首部,發(fā)送出去,等待返回。
由于 IP 只提供最好的數(shù)據(jù)報(bào)傳輸服務(wù),但不保證一定成功送達(dá),也就是說(shuō),出了問(wèn)題,直接就把報(bào)文丟棄了,取決于網(wǎng)絡(luò)狀況。
服務(wù)器收到 ICMP 請(qǐng)求報(bào)文時(shí),會(huì)做相應(yīng)的回應(yīng),但是現(xiàn)在的一些安全策略可以禁用 ping,也就是雖然網(wǎng)絡(luò)是連通的,但 ping 也沒(méi)有得到響應(yīng)。
因此,如果超過(guò)一定的時(shí)間,ping 客戶端還沒(méi)有收到返回的話,這個(gè)數(shù)據(jù)包就認(rèn)為是丟了,顯示超時(shí)。如果收到的話,就計(jì)算往返時(shí)間,然后回顯 ttl、time 等信息。當(dāng)按下 Ctrl C 時(shí),計(jì)算統(tǒng)計(jì)信息并顯示。
如果對(duì)《TCP IP 詳解》感興趣,可以購(gòu)買(mǎi)紙質(zhì)書(shū),也可以回復(fù)「TCPIP」獲取電子書(shū)。
