/
teterkin
/
vm_load_testing
Обзор
Документация
Войти
/
teterkin
/
vm_load_testing
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/network.rs
111 строк
3 KB
alexefan136
upload files
12 ноя 2025, 18:00
12 ноя 2025, 18:00
eb766a0
Код
Авторство
О чём код?
// src/network.rs use std::time::Instant; use tokio::net::TcpStream; #[derive(Debug, Clone)] pub struct NetworkResult { pub tcp_rtt_ms: f64, pub http_dl_mib_s: f64, pub interface_info: Vec<InterfaceInfo>, } #[derive(Debug, Clone)] pub struct InterfaceInfo { pub name: String, pub mtu: u32, pub driver: Option<String>, } const TIMEOUT_SECS: u64 = 20; /// Выполняет сетевые тесты: latency и bandwidth. pub async fn bench_network() -> NetworkResult { let tcp_rtt_ms = measure_tcp_rtt().await; let http_dl_mib_s = measure_http_bandwidth().await; let interface_info = collect_interface_info(); NetworkResult { tcp_rtt_ms, http_dl_mib_s, interface_info, } } /// Замеряет TCP RTT до 1.1.1.1:80 (без TLS, быстро, без root). async fn measure_tcp_rtt() -> f64 { let start = Instant::now(); let res = tokio::time::timeout( std::time::Duration::from_secs(5), TcpStream::connect("1.1.1.1:80") ).await; if res.is_ok() { start.elapsed().as_secs_f64() * 1000.0 } else { -1.0 // ошибка подключения } } /// Замеряет пропускную способность через HTTP-загрузку 100 MiB. async fn measure_http_bandwidth() -> f64 { let client = reqwest::Client::new(); let url = "https://httpbin.org/stream-bytes/104857600"; // 100 MiB let start = Instant::now(); let res = tokio::time::timeout( std::time::Duration::from_secs(TIMEOUT_SECS), client.get(url).send() ).await; match res { Ok(Ok(resp)) => { let _ = tokio::time::timeout( std::time::Duration::from_secs(TIMEOUT_SECS), resp.bytes() ).await; let elapsed = start.elapsed().as_secs_f64(); if elapsed > 0.1 { 100.0 / elapsed // 100 MiB / sec → MiB/s } else { 0.0 } } _ => 0.0, } } /// Собирает информацию о сетевых интерфейсах из /sys/class/net. fn collect_interface_info() -> Vec<InterfaceInfo> { let mut interfaces = Vec::new(); let net_path = "/sys/class/net"; if let Ok(entries) = std::fs::read_dir(net_path) { for entry in entries.flatten() { let name = entry.file_name().to_string_lossy().into_owned(); if name == "lo" { continue; } // пропускаем loopback // MTU let mtu = std::fs::read_to_string(format!("{}/{}/mtu", net_path, name)) .ok() .and_then(|s| s.trim().parse().ok()) .unwrap_or(1500); // Драйвер (если доступен) let driver = std::fs::read_link(format!("{}/{}/device/driver", net_path, name)) .ok() .and_then(|path| { path.file_name() .map(|os_str| os_str.to_string_lossy().into_owned()) }); interfaces.push(InterfaceInfo { name, mtu, driver, }); } } interfaces }