1. 程式人生 > >差網路模擬工具---clumsy

差網路模擬工具---clumsy

我們開發基於網路的應用時,經常需要考慮當網路較差時的異常處理,clumsy就是這個可以用來進行網路延遲的工具,可以實時的修改網路延遲、丟包、篡改等網路異常情況。 clumsy 能在 Windows 平臺下人工造成不穩定的網路狀況,方便你除錯應用程式在極端網路狀況下的表現。 簡介 利用封裝 Winodws Filtering Platform 的WinDivert 庫, clumsy 能實時的將系統接收和發出的網路資料包攔截下來,人工的造成延遲,掉包和篡改操作後再進行傳送。無論你是要重現網路異常造成的程式錯誤,還是評估你的應用程式在不良網路狀況下的表現,clumsy 都能讓你在不需要額外新增程式碼的情況下,在系統層次幫你達到想要的效果: 特色: 下載即用,不需要安裝任何東西。 不需要額外設定,不需要修改你的程式的程式碼。 系統級別的網路控制,可以適用於命令列,圖形介面等任何 Windows 應用程式。 不僅僅只支援 HTTP,任何 TCP, UDP 的網路連線都可以被處理。 支援本地除錯(伺服器和客戶端都在 localhost) "熱插拔",你的程式可以一直執行,而 clumsy 可以隨時開啟和關閉。 實時調節各種引數,詳細控制網路情況。 clumsy 首先根據使用者選擇的 filter 來攔截指定的網路資料。在 filter 中可以設定你感興趣的協議(tcp/udp),埠號,是接收還是發出的埠。你也可以通過簡單的邏輯語句來進一步縮小範圍。當 clumsy 被啟用時,只有符合這些標準的網路資料會被進行處理,而你不感興趣的資料仍然會由系統正常傳輸。 當被 filter 的網路資料包被攔截後,你可以選擇 clumsy 提供的功能來有目的性的調整網路情況:         1. 延遲(Lag),把資料包快取一段時間後再發出,這樣能夠模擬網路延遲的狀況。       2. 掉包(Drop),隨機丟棄一些資料。         3. 節流(Throttle),把一小段時間內的資料攔截下來後再在之後的同一時間一同發出去。         4. 重發(Duplicate),隨機複製一些資料並與其本身一同傳送。         5. 亂序(Out of order),打亂資料包傳送的順序。         6. 篡改(Tamper),隨機修改小部分的包裹內容。 儘管當前寬頻網路連線十分普及,但網路傳輸其本身在本質上總不是穩定的。如果你的應用程式中沒有應對各種情況的處理,那麼有可能一個丟失的 UDP 包裹都會讓你的程式崩潰。正確的除錯這類行為 顯然需要再程式碼結構上進行仔細的設計和處理,還會很花功夫。而且在某些封裝緊密的開發環境(

Unity3D 自帶的網路庫可能是一個例子)下會更麻煩。clumsy 以儘可能減輕程式設計師負擔為目標, 希望提供一個簡單方便(但並不完美)的解決方案。 專案的程式碼可以在github上獲取。在下載頁面有編譯好的版本。強烈建議在使用前花點時間閱讀一下文件,來了解 clumsy 的功能和限制。

術語 為了後文閱讀方便,這裡列出本頁面中反覆使用的一些術語。 回送資料包(Loopback packets):從本機 (可以簡單理解為 127.0.0.1) 傳送到本機的資料包。通常在除錯程式的時候為了配置簡單,很多情況下就是簡單的把伺服器和客戶端都架設在一臺機器上,回送資料包在這種情況下就很常見。 輸入資料包(Inbound packets):當前計算機接收到的資料包。其來源可能是網路上的其他機器,也可能就是本機。 輸出資料包(Outbound packets): 從當前計算機發送出去的資料包。 資料包過濾(Filtering): 大部分情況你只對所有的資料包的一個子集感興趣。在 clumsy裡你可以提供一個 filter 來指定你感興趣的資料包傳送至/傳送於某個 IP,包裹協議,以及一些其他的標準。 資料包捕獲(Capturing packets): 根據之前設定的 filter, clumsy 會攔截下這些符合標準的資料包。在你的程式發出資料包之後,或者再接受到資料包之前,clumsy 會攔截下這些包裹進行處理,進行指定的處理來達到模擬劣化網路環境的效果。 重新注入資料包(Reinjecting packets):在資料包被攔截下來後,他們還是需要被重新發送給目標的埠,這樣應用程式才能接收到它們並繼續工作。這個步驟科學的講就叫做重新注入 (reinjecting) 資料包。

限制 這部分內容非常重要,請務必不要略過。 目前的實現中有一些難以繞過的限制和問題,列表如下: 1. 回送的輸入資料包(Loopback inbound packets)無法被重新注入。 仔細想想你就會發現我們沒有很好的方法來區分一個回送資料包到底是被髮出還是被接收到,因為它們的目標和來源 IP 地址都是本機。事實上 clumsy 底層的 WinDivert,以及其基於的 Windows Filtering Platform 把所有的回送資料包統統認為是輸出 (Outbound) 資料包。這裡需要記住的是,當你在本機上處理回送資料包的時候,你不能把 "inbound" 設定在 filter 條件中,最簡單的方法就是在條件中簡單的加上 "outbound"。另一件容易出問題的事情是,你本機的 IP 不僅僅只有 127.0.0.1 一個,還有類似路由器分配給你機器的 IP也是屬於你的本機 IP。 2. 回送資料包會被處理兩次。 因為所有的回送資料包都被認為是輸出資料包,clumsy 會重複處理它們兩次。一次是在發出的時候,一次是在接受到的時候。一個簡單的例子是簡單的把 filter 設定為 outbound,然後在 clumsy 中設定 500ms 的延遲並開啟,之後在命令列裡 ping localhost。這時你會發現延遲是 1000ms。當然你可以仔細的設定 filter 條件通過設定埠來只捕捉一部分的回送資料包,但是這樣會比較麻煩。最簡單的做法就是記住這個問題,然後設定引數的時候做相應的計算。 3. 輸入資料包的重新注入有些問題。 根據上面的描述,回送的輸入包裹無法被重新注入。問題是現在有些來自包裹雖然其地址不是本機的 IP,其偶爾也會被認為是輸入包裹。這種情況如果被捕捉到是無法進行重新注入的。這個問題僅僅影響非回送資料包,所以如果你僅僅是在本機上除錯伺服器和客戶端那麼是不會有這個問題的。未來版本的目標是準確的重現這個問題並進行修復。

4. 無法根據程序來進行資料包過濾。 全系統級的資料包捕獲雖然被列在了功能裡,實際上是在當前的實現下,沒法找到一個合適且穩定的方法來進行根據程序的資料包捕獲。

如何使用 首先請根據你係統的版本(32位或64位)下載 clumsy 最新版本。注意如果你安裝的是64位的系統那麼一定要下載64位的 clumsy。另一件重要的事實 clumsy 需要管理員許可權才能正常工作。雙擊開啟 clumsy 的話會彈出 UAC 對話方塊。如果沒有的話請右鍵點選 clumsy.exe 選擇"以管理員身份執行"。

當你輸入了 filter 點選 '開始' 後,clumsy 就已經開始截獲包裹。這個一定會有一定的效率損失。但好訊息是 clumsy 本身就是為了模擬網路狀況糟糕的軟體所以這個問題不是很嚴重。 另一方面,你應該精確的設定 filter 的內容,讓它儘可能準確的捕捉你感興趣的資料包。 延遲比在 Lag 裡設定的要嚴重很多。 這個問題的重點在於,clumsy 裡面的設定並不是準確的可以用來做測速的值。其作用更傾向於作為引數控制軟體的行為。 另一個需要理解的是,這裡的延遲是作用於每一個網路包裹的。比如建立一個 TCP 連線需要至少 3 個包裹。那麼如果 clumsy 引入了 20ms 的延遲,對於每一個TCP 連線則至少引入了 3*20=60ms 的延遲。如果是要載入一個網頁的話,有部分 HTTP 請求必須是要按順序完成後頁面才能開始渲染。假如要完成 1, 2, 3 這三個請求,那麼 clumsy 在這裡至少引入了 3*60=180ms 的延遲。 所以說如果 clumsy 讓網路變的很慢的話也不用太擔心。

類似功能軟體,如果 clumsy 不能滿足你的需求你可以試試這些: Network Emulator for Windows Toolkit (Windows) - 微軟提供的網路模擬工具。 ipfw or pfctl (FreeBSD/OSX) - BSD 下的網路模擬工具。 wipfw (Windows) - ipfw Windows 移植,但功能只有 ipfw 的一個子集。 netem (Linux) - Linux Kernel 提供的網路模擬。 tc (Linux) - 配置 Linux Kernel 的網路流量控制。 Throttle (Mac) - 通過分享無限網路來模擬 3G 網路。 Network Link Conditioner (Mac) - XCode 自帶的網路模擬工具。

根據上圖中的數字圖示順序:

1. Filter。詳細的 filter 語法在下一部分有仔細的講解。但是簡單的講它跟你常見的程式語言中的 if 中的條件寫法幾乎一樣。資料包將根據這個標準被攔截。

2. 預設 Filte。 這裡提供了一系列內建的預設 Filter 供你使用。你可以通過參考他們來寫你自己需要的 Filter,也可以把你發現常用的 filter 寫到 clumsy.exe 所在資料夾下的 config.txt中。

3. 開始/結束 按鈕。點選此按鈕 clumsy 就會開始捕捉資料包。在某些情況下,比如提供的filter 語法有問題 clumsy 無法正常開始工作。請參考底部的提示進行操作。如果一切正常按鈕上的文字會變為 "Stop",按下就會停止捕捉包裹,系統網路會恢復正常。按鈕左邊有一個小圖示,每當資料包被捕獲的時候它會變綠,當包裹重新注入失敗的時候它會變紅色。這時你應該考慮是否遇到了上面限制中提到的問題。另外需要提到的是開啟和結束可

以隨時進行並實時生效。

4. 功能控制。勾選功能對應的選框來開啟對應的功能。每個功能左邊也有一個小圖示,其起作用的時候就會變綠。在資料包捕獲開啟的狀態下,你可以實時開啟/關閉任何功能,它們都會即時生效。

5. 引數控制。對每個功能,都附有對應的引數控制控制元件讓你進行詳細的配置。其中最常見的有:

Inbound/Outbound: 是否處理輸入/輸出資料包。這裡在 filter 的控制之外額外提供一個選擇的機會,並且也可以在實時生效。

Chance: 功能生效的概率。顯然你需要把它們設定在一個合理的範圍內才不會讓網路在可以接受的範圍內劣化。

6. 狀態。顯示 clumsy 當前狀態的幫助資訊。

Filter 語法

這裡 filter 中提供的語句會被直接作為引數提供給 WinDivert。語法在 WinDivert 的文件中有詳細的描述。如果你寫過一點程式你會發現這個語法跟你放在 if 裡面的判斷表示式非常類似。你可以用 and, or, not 和 括號 來表達簡單的邏輯規則。類似 =, !=, ‹, › 的操作符也可以被使用。下面是 filter 中可以使用的變數的列表(直接拷貝自 WinDivert 的文件)。你也可以通過以預設的 filter作為例子參考。

下載地址: