7 个不稳定版本 (3 个重大更改)
0.4.2 | 2023年11月27日 |
---|---|
0.4.1 | 2023年11月27日 |
0.3.0 | 2023年10月14日 |
0.2.0 | 2023年10月12日 |
0.1.5 | 2023年10月10日 |
#725 in 网络编程
45KB
934 行
mping-rs
一个多目标ping工具,支持每秒10,000个数据包,精确的延迟。
一个高频ping工具,支持多个目标。正常的ping通常用作探测工具,mping还可以用作压力测试工具。Go版本: smallnest/mping
您还可以将其作为库来实现您的多目标并处理ping结果。请参阅示例文件夹中的 ping.rs
示例。
用法 - 作为工具
编译
cargo build --release
选项用法。
> $$ mping -h
mping 0.4.2
A multi-targets ping tool, which supports 10,000 packets/second.
USAGE:
mping [OPTIONS] <ip address>...
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-c, --count <count> max packet count
-d, --delay <delay> delay in seconds [default: 3]
-r, --rate <rate> rate in packets/second [default: 100]
-s, --size <size> payload size [default: 64]
-w, --timeout <timeout> timeout in seconds [default: 1]
-z, --tos <tos> type of service
-t, --ttl <ttl> time to live [default: 64]
ARGS:
<ip address>... one ip address or more, e.g. 127.0.0.1,8.8.8.8/24,bing.com
示例
sudo ./mping -r 5 8.8.8.8
sudo ./mping -r 100 8.8.8.8/30,8.8.4.4,github.com
sudo ./mping -r 100 github.com,bing.com
docker
sudo docker run --rm -it smallnest/mping-rs:latest 8.8.8.8
用法 - 作为库
一次性ping一个目标
use std::env;
use std::process;
use std::time::Duration;
use std::net::{IpAddr, ToSocketAddrs};
use mping::ping_once;
/// ping a target as an example of ping_once.
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
println!("Usage: {} <ip-address>", args[0]);
process::exit(1);
}
let addr = args[1].clone();
match ping_once(addr, Some(Duration::from_secs(2)), Some(1234), Some(64), None, Some(64)) {
Ok((bitflip,latency)) => {
println!("bitflip: {}, latency: {:.2}ms", bitflip, latency.as_secs_f64()*1000.0);
}
Err(e) => {
println!("error: {:?}", e);
}
}
}
永久ping多个目标
use std::env;
use std::process;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
use std::net::{IpAddr, ToSocketAddrs};
use ::mping::{ping, PingOption};
/// A multi-targets ping example, which use mping crate.
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
println!("Usage: {} <ip-address>", args[0]);
process::exit(1);
}
let pid = process::id() as u16;
let target = args[1].clone();
let addr = parse_ip(&target);
let addrs = vec![addr.parse().unwrap()];
let popt = PingOption {
timeout: Duration::from_secs(1),
ttl: 64,
tos: None,
ident: pid,
len: 56,
rate: 100,
rate_for_all: false,
delay: 3,
count: None,
};
let (tx, rx) = mpsc::channel();
thread::spawn(move || match ping(addrs, popt, false, Some(tx)) {
Ok(_) => {}
Err(e) => {
println!("error: {:?}", e);
}
});
for tr in rx {
let total = tr.received + tr.loss;
let loss_rate = if total == 0 {
0.0
} else {
(tr.loss as f64) / (total as f64)
};
if tr.received == 0 {
println!(
"{}: sent:{}, recv:{}, loss rate: {:.2}%, latency: {}ms",
addr,
total,
tr.received,
loss_rate * 100.0,
0
)
} else {
println!(
"{}: sent:{}, recv:{}, loss rate: {:.2}%, latency: {:.2}ms",
addr,
total,
tr.received,
loss_rate * 100.0,
Duration::from_nanos(tr.latency as u64 / (tr.received as u64)).as_secs_f64()
* 1000.0
)
}
}
}
fn parse_ip(s: &str) -> String {
if let Ok(_) = s.parse::<IpAddr>() {
return s.to_string();
} else if let Ok(addrs) = (s, 0).to_socket_addrs() {
for addr in addrs {
if let IpAddr::V4(ipv4) = addr.ip() {
return IpAddr::V4(ipv4).to_string();
}
}
}
s.to_string()
}
依赖关系
~8–18MB
~219K SLoC