最近用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();
}