速讀原著-TCP/IP(Ping程式)
- 2020 年 3 月 6 日
- 筆記
7.2 Ping程式
我們稱發送回顯請求的 p i n g程式為客戶,而稱被 p i n g的主機為伺服器。大多數的 T C P / I P實現都在內核中直接支援 P i n g伺服器—這種伺服器不是一個用戶進程(在第 6章中描述的兩種I C M P查詢服務,地址掩碼和時間戳請求,也都是直接在內核中進行處理的)。
I C M P回顯請求和回顯應答報文如圖 7 - 1所示。

對於其他類型的I C M P查詢報文,伺服器必須響應標識符和序列號欄位。另外,客戶發送的選項數據必須回顯,假設客戶對這些資訊都會感興趣。
U n i x系統在實現p i n g程式時是把I C M P報文中的標識符欄位置成發送進程的 I D號。這樣即使在同一台主機上同時運行了多個 p i n g程式實例,p i n g程式也可以識別出返回的資訊。序列號從0開始,每發送一次新的回顯請求就加 1。p i n g程式列印出返回的每個分組的序列號,允許我們查看是否有分組丟失、失序或重複。 I P是一種最好的數據報傳遞服務,因此這三個條件都有可能發生。
舊版本的p i n g程式曾經以這種模式運行,即每秒發送一個回顯請求,並列印出返回的每個回顯應答。但是,新版本的實現需要加上- s選項才能以這種模式運行。默認情況下,新版本的p i n g程式只發送一個回顯請求。如果收到回顯應答,則輸出「 host is alive」;否則,在2 0秒內沒有收到應答就輸出「 no answer(沒有回答)」。
7.2.1 LAN輸出
在區域網上運行p i n g程式的結果輸出一般有如下格式:

當返回I C M P回顯應答時,要列印出序列號和 T T L,並計算往返時間( T T L位於I P首部中的生存時間欄位。當前的 B S D系統中的 p i n g程式每次收到回顯應答時都列印出收到的 T T L—有些系統並不這樣做。我們將在第 8章中通過t r a c e r o u t e程式來介紹T T L的用法)。
從上面的輸出中可以看出,回顯應答是以發送的次序返回的( 0,1,2等)。p i n g程式通過在I C M P報文數據中存放發送請求的時間值來計算往返時間。當應答返回時,用當前時間減去存放在 I C M P報文中的時間值,即是往返時間。注意,在發送端 b s d i上,往返時間的計算結果都為 0 ms。這是因為程式使用的計時器解析度低的原因。 B S D / 3 8 6版本0 . 9 . 4系統只能提供10 ms級的計時器(在附錄B中有更詳細的介紹)。在後面的章節中,當我們在具有較高解析度計時器的系統上( S u n)查看t c p d u m p輸出時會發現,I C M P回顯請求和回顯應答的時間差在4 ms以下。
輸出的第一行包括目的主機的 I P地址,儘管指定的是它的名字( s v r 4)。這說明名字已經經過解析器被轉換成 I P地址了。我們將在第 1 4章介紹解析器和 D N S。現在,我們發現,如果敲入p i n g命令,幾秒鐘過後會在第 1行列印出I P地址,D N S就是利用這段時間來確定主機名所對應的I P地址。
本例中的t c p d u m p輸出如圖7 - 2所示。從發送回顯請求到收到回顯應答,時間間隔始終為 3.7 ms。還可以看到,回顯請求大約每隔1秒鐘發送一次。
通常,第1個往返時間值要比其他的大。這是由於目的端的硬體地址不在 A R P高速快取中

的緣故。正如我們在第 4章中看到的那樣,在發送第一個回顯請求之前要發送一個 A R P請求並接收A R P應答,這需要花費幾毫秒的時間。下面的例子說明了這一點:

第1個RT T中多出的3 ms很可能就是因為發送A R P請求和接收A R P應答所花費的時間。這個例子運行在s u n主機上,它提供的是具有微秒級解析度的計時器,但是 p i n g程式只能列印出毫秒級的往返時間。在前面運行於 BSD/386 0.9.4版上的例子中,列印出來的往返時間值為0 ms,這是因為計時器只能提供 1 0 m s的誤差。下面的例子是BSD/386 1.0版的輸出,它提供的計時器也具有微秒級的解析度,因此, p i n g程式的輸出結果也具有較高的解析度。

7.2.2 WAN輸出
在一個廣域網上,結果會有很大的不同。下面的例子是在某個工作日的下午即 I n t e r n e t具有正常通訊量時的運行結果:

這裡,序列號為1、2、3、4、6、1 0、11、1 2和1 3的回顯請求或回顯應答在某個地方丟失了。另外,我們注意到往返時間發生了很大的變化(像 5 2 %這樣高的分組丟失率是不正常的。
即使是在工作日的下午,對於 I n t e r n e t來說也是不正常的)。通過廣域網還有可能看到重複的分組(即相同序列號的分組被列印兩次或更多次),失序的分組(序列號為N + 1的分組在序列號為N的分組之前被列印)。
7.2.3 線路SLIP鏈接
讓我們再來看看 S L I P鏈路上的往返時間,因為它們經常運行於低速的非同步方式,如 9 6 0 0 b / s或更低。回想我們在 2 . 1 0節計算的串列線路吞吐量。針對這個例子,我們把主機 b s d i和s l i p之間的S L I P鏈路傳輸速率設置為1200 b/s。
下面我們可以來估計往返時間。首先,從前面的 P i n g程式輸出例子中可以注意到,默認情況下發送的I C M P報文有5 6個位元組。再加上2 0個位元組的I P首部和8個位元組的I C M P首部,I P數據報的總長度為 8 4位元組(我們可以運行 t c p d u m p-e命令查看乙太網數據幀來驗證這一點)。
另外,從2 . 4節可以知道,至少要增加兩個額外的位元組:在數據報的開始和結尾加上 E N D字元。此外,S L I P幀還有可能再增加一些位元組,但這取決於數據報中每個位元組的值。對於 1200 b/s這個速率來說,由於每個位元組含有 8 bit數據、1 bit起始位和1 bit結束位,因此傳輸速率是每秒1 2 0個位元組,或者說每個位元組 8.33 ms。所以我們可以估計需要 1 4 3 3(8 6×8 . 3 3×2)m s(乘2 是因為我們計算的是往返時間)。
下面的輸出證實了我們的計算:

(對於S V R 4來說,如果每秒鐘發送一次請求則必須帶- s選項)。往返時間大約是 1 . 5秒,但是程式仍然每間隔 1秒鐘發送一次 I C M P回顯請求。這說明在第 1個回顯應答返回之前(1 . 4 8 0秒時刻)就已經發送了兩次回顯請求(分別在 0秒和1秒時刻)。這就是為什麼總結行指出丟失了一個分組。實際上分組並未丟失,很可能仍然在返回的途中。我們在第8章討論t r a c e r o u t e程式時將回頭再討論這種低速的 S L I P鏈路。
7.2.4 撥號SLIP鏈路
對於拔號 S L I P鏈路來說,情況有些變化,因為在鏈路的兩端增加了數據機。用在s u n和n e t b系統之間的數據機提供的是 V. 3 2調製方式( 9600 b/s)、V. 4 2錯誤控制方式(也稱作L A P - M)以及V. 4 2 b i s數據壓縮方式。這表明我們針對線路鏈路參數進行的簡單計算不再準確了。
很多因素都有可能影響。數據機帶來了時延。隨著數據的壓縮,分組長度可能會減小,但是由於使用了錯誤控制協議,分組長度又可能會增加。另外,接收端的數據機只能在驗證了循環檢驗字元(檢驗和)後才能釋放收到的數據。最後,我們還要處理每一端的電腦非同步串列介面,許多作業系統只能在固定的時間間隔內,或者收到若干字元後才去讀這些介面。
作為一個例子,我們在s u n主機上p i n g主機g e m i n i,輸出結果如下:

注意,第1個RT T不是10 ms的整數倍,但是其他行都是 10 ms的整數倍。如果我們運行該程式若干次,發現每次結果都是這樣(這並不是由 s u n主機上的時鐘解析度造成的結果,因為根據附錄B中的測試結果可以知道它的時鐘能提供毫秒級的解析度)。
另外還要注意,第1個RT T要比其他的大,而且依次遞減,然後徘徊在 2 8 0~300 ms之間。我們讓它運行1 ~ 2分鐘,RT T一直處於這個範圍,不會低於 260 ms。如果我們以9600 b/s的速率計算RT T(習題7 . 2),那麼觀察到的值應該大約是估計值的 1 . 5倍。
如果運行p i n g程式6 0秒鐘並計算觀察到的 RT T的平均值,我們發現在 V. 4 2和V. 4 2 b i s模式下平均值為277 ms(這比上個例子列印出來的平均值要好,因為運行時間較長,這樣就把開始較長的時間平攤了)。如果我們關閉V. 4 2 b i s數據壓縮方式,平均值為330 ms。如果我們關閉V. 4 2錯誤控制方式(它同時也關閉了 V. 4 2 b i s數據壓縮方式),平均值為300 ms。這些數據機的參數對RT T的影響很大,使用錯誤控制和數據壓縮方式似乎效果最好。
