網路已經是現代生活不可或缺的一部分,但是當我們需要通過網路來獲取或傳送資料時,網路的速度就顯得非常重要。那麼要如何準確地知道我們的網路速度是多少呢?通常我們會選擇使用一些線上的網路測速工具,或者我們可以自己實作一個本地的網路測速工具。
Rust 是一個提供記憶體安全、並發和高效能的系統程式設計語言,它非常適合用於實作這類的系統工具。在這篇文章中,我們將透過 Rust 語言,從零開始實作一個簡單的網路測速小工具。透過這個小工具,我們可以輕鬆地在本地環境中測試我們的網路下載速度,以後就不用再使用線上的網路測速工具了。
安裝套件
首先在專案中安裝 reqwest
和 tokio
套件,reqwest
會處理 HTTP Client 的部分,tokio
則是處理非同步執行。
[dependencies]
reqwest = "0.11.20"
tokio = { version = "1.32.0", features = ["full"] }
網路測速的原理
網路測速的原理,會透過下載一個檔案,並且計算下載的速度,其實就是計算下載的資料量除以下載的時間,就可以得到下載的速度,計算公式如下:
下載速度 = 下載的資料量 / 下載的時間
如果是下載一個 200 MB 的檔案,並且下載的時間是 10 秒,那麼下載的速度就是 20 MB/s。
但是這個速度跟我們平常看到的網路速度不太一樣,因為我們平常看到的網路速度是指的資料傳輸的速度,而不是下載的速度,所以我們需要將下載的速度換算成資料傳輸的速度,換算公式如下:
資料傳輸速度 = 下載的速度 * 8
如果是下載一個 200 MB 的檔案,並且下載的時間是 10 秒,那麼下載的速度就是 20 MB/s,資料傳輸的速度就是 160 Mbps。
如何實作
知道原理是透過下載一個檔案來測試網路的下載速度,我們就可以實際來做看看。
會使用 reqwest::get()
來發送 HTTP 請求,並且使用 response.bytes()
來取得下載的資料,最後計算下載的速度。
use reqwest;
use std::time::Instant;
#[tokio::main]
async fn main() {
let url = "http://http.speed.hinet.net/test_200m.zip";
println!("開始測試下載速度...");
let start_time = Instant::now();
match reqwest::get(url).await {
Ok(response) => {
if !response.status().is_success() {
println!("測試下載時發生錯誤: {:?}", response.status());
return;
}
match response.bytes().await {
Ok(bytes) => {
let duration = start_time.elapsed();
let speed_in_mbps =
(bytes.len() * 8) as f64 / duration.as_secs_f64() / 1_000_000.0;
println!("網路下載速度: {:.2} Mbps", speed_in_mbps);
println!("下載完成,耗時: {:.2} 秒", duration.as_secs_f64());
}
Err(e) => {
println!("讀取下載資料時發生錯誤: {:?}", e);
}
}
}
Err(e) => {
println!("下載時發生錯誤: {:?}", e);
}
}
}
這裡並不會下載檔案到你的電腦中,而是會將檔案下載到記憶體中,所以不用擔心會佔用到你的硬碟空間。不過如果選擇下載的檔案太大,可能會導致記憶體不足,所以要注意一下。
這邊選擇下載的檔案是 200 MB 的檔案,可以參考中華電信提供的測試檔案。
接下來在終端機執行 cargo run
,就可以看到測試的結果。
Bonus
現在測試的過程中,只會顯示一串文字「開始測試下載速度…」,感覺有點無聊,所以來加入一點動態的效果。
let loading_dots_task = task::spawn(async {
let mut count = 0;
loop {
sleep(Duration::from_secs(1)).await;
count += 1;
if count <= 3 {
print!(".");
} else {
// 重置計數器並移動游標回到起始位置,再次開始 print
count = 0;
print!("\r開始測試下載速度 ");
}
// 強制立即輸出不緩存
std::io::stdout().flush().unwrap();
}
});
這一段程式碼會在背景執行,每隔一秒鐘就會顯示一個點,並且在顯示三個點之後,就會清除畫面,並且再次顯示「開始測試下載速度」。
最後要加上一段 code,終止 task 的執行。
loading_dots_task.abort();
最後看一下執行的結果:
總結
透過實作這個小工具,我們可以看到 Rust 語言在系統程式設計方面的強大能力,它不僅能讓我們輕鬆地實作出高效且安全的系統工具,也提供了豐富的生態圈支持,讓我們能快速地完成開發任務,期待在未來能夠在更多的領域中看到 Rust 語言的身影。
📚 五倍學院全新線上直播課程 | 為你自己學 Rust 🦀
帶你認識 Rust 語言的核心概念,從資料型態、變數與常數、函數和閉包,帶你全面掌握 Rust 獨特使用性,用更安全又高效的方式處理記憶體,打造更好的應用程式
✅日期:1/15 (一) & 1/17 (三)
✅時間:19:00 - 22:00
✅立即報名:https://5xcamp.us/AfgkdR
✅原價 NT 1,450 元,限時優惠價 NT 999 元 !