最近用Rust写了个pinger和ponger,pinger每5s向ponger发一个udp包, ponger会把这个消息打印到终端。
但是发现pinger一直在自顾自地ping,ponger那里一条日志都没收到。
先用tcpdump抓包sudo tcpdump -i lo port 8888
:
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 262144 bytes
10:50:34.290607 IP localhost.8888 > localhost.8888: UDP, length 24
10:50:39.291118 IP localhost.8888 > localhost.8888: UDP, length 24
10:50:44.291684 IP localhost.8888 > localhost.8888: UDP, length 24
10:50:49.292292 IP localhost.8888 > localhost.8888: UDP, length 24
10:50:54.292864 IP localhost.8888 > localhost.8888: UDP, length 24
sudo tcpdump -i lo port 6666
抓ponger,发现没有收到包消息。
nc -z -u -v localhost 6666
同时抓ponger,发现ponger可以正常接发包。
不知道哪里出问题了,请教各位。。
最后附上代码:
// Pinger
use async_std::net::{SocketAddr, UdpSocket};
use futures_timer::Delay;
use log::{error, info};
use simplelog::{CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode};
use futures::future::join_all;
use std::{io::Read, sync::Arc, time::Duration};
pub struct UdpPinger {
// targets:
pub targets: Vec<SocketAddr>,
pub delay_secs: u64,
}
impl UdpPinger {
pub async fn run(self) -> std::io::Result<()> {
let listener = async_std::net::UdpSocket::bind("127.0.0.1:8888")
.await
.expect("couldn't bind");
let listener: Arc<UdpSocket> = Arc::new(listener);
let self_addr = listener.local_addr().unwrap().to_string();
let delay_secs = self.delay_secs;
join_all(
self.targets
.into_iter()
.zip([listener].iter().cloned())
.zip([self_addr].iter().cloned())
.map(|(self_addr, target)| async move {
let ((addr, listener), tar) = (self_addr, target);
let d = Duration::from_secs(delay_secs);
loop {
// std::thread::sleep(std::time::Duration::from_secs(1));
match listener
.send_to(format!("ping from {}", &addr).as_bytes(), &tar)
.await
{
Err(e) => error!("{:?}", e.to_string()),
Ok(_) => info!("ping {}", &addr),
}
Delay::new(d).await;
}
}),
)
.await;
// println!("done");
info!("pinger done");
Ok(())
}
}
fn main() {
let _ = CombinedLogger::init(vec![TermLogger::new(
LevelFilter::Info,
Config::default(),
TerminalMode::Mixed,
)]);
info!(
"working at {}",
std::env::current_dir().unwrap().to_str().unwrap()
);
match std::fs::File::open("./conf/targets") {
Ok(mut f) => {
let mut s = String::new();
match f.read_to_string(&mut s) {
Ok(_) => {
async_std::task::block_on(
UdpPinger {
targets: s
.split_whitespace()
.map(|tar| tar.parse().unwrap())
.collect(),
delay_secs: 5,
}
.run(),
)
.unwrap();
}
Err(e) => error!("{}", e.to_string()),
}
}
Err(e) => error!("{}", e.to_string()),
}
}
// Ponger
use simplelog::{CombinedLogger, Config, LevelFilter, TermLogger, TerminalMode};
use async_std::net::SocketAddr;
use log::info;
pub struct FakeHost {
pub addr: SocketAddr,
}
impl FakeHost {
pub async fn run(self) -> std::io::Result<()> {
let listener = async_std::net::UdpSocket::bind(self.addr).await?;
let quit = false;
let mut buf = [0u8; 512];
info!("ponger up {}", listener.local_addr().unwrap().to_string());
while !quit {
let (sz, peer) = listener.recv_from(&mut buf).await?;
info!(
"from {}: {}",
peer.to_string(),
String::from_utf8_lossy(&buf[..sz])
);
// echo
//listener.send_to(&buf[..sz], peer).await?;
}
info!("ponger done");
Ok(())
}
}
fn main() {
let _ = CombinedLogger::init(vec![TermLogger::new(
LevelFilter::Info,
Config::default(),
TerminalMode::Mixed,
)]);
async_std::task::block_on(
FakeHost {
addr: "127.0.0.1:6666".parse().unwrap(),
}
.run(),
)
.unwrap();
}