use std::net::Ipv4Addr; use std::process::Command; use std::sync::mpsc::Sender; use std::thread; use std::time::{Duration, SystemTime}; use crate::ping_request::PingRequest; use crate::ping_result::PingResult; use crate::SECONDS_BETWEEN_PING; pub struct Manager; const WIN_PING_SUCCESS: i32 = 1; const LIN_PING_SUCCESS: i32 = 0; impl Manager { pub fn spawn_manager_thread(targets: Vec, sender: Sender) { let local_targets = targets.clone(); thread::spawn(move || { loop { for target in &local_targets { Manager::spawn_single_ping(PingRequest { target: *target }, sender.clone()); } thread::sleep(Duration::from_secs(SECONDS_BETWEEN_PING as u64)); } }); } // Spawns a thread that pings a target and sends the response back to the main thread // via the sender fn spawn_single_ping(request: PingRequest, sender: Sender) { let local_request = request.clone(); thread::spawn(move || { let mut result = 0; let mut success = true; let start_time = SystemTime::now(); #[cfg(any(target_os="windows"))] { result = Command::new("c:/windows/system32/ping.exe").arg(request.target.to_string()) .arg("-n 1") .arg(format!("-w {}", crate::SECONDS_BETWEEN_PING)) .arg("-4") .output().unwrap().status.code().unwrap_or(255); success = result == WIN_PING_SUCCESS as i32;; } #[cfg(any(target_os="linux"))] { result = Command::new("/usr/bin/ping").arg(request.target.to_string()) .arg("-c 1") .arg("-4") .arg(format!("-w {}", SECONDS_BETWEEN_PING)) .arg("-W 1") .output().unwrap().status.code().unwrap_or(255); success = result == LIN_PING_SUCCESS as i32; } let ping_duration = SystemTime::now() .duration_since(start_time) .unwrap_or(Duration::from_secs(600)); let success = ping_duration.as_millis() >= SECONDS_BETWEEN_PING as u128 && success; sender.send(PingResult { target: local_request.target, success, rtt: ping_duration.as_millis() as u32 }).expect("Unable to send response"); // println!("Attempt for for {}", local_request.target); }); } }