You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UDP单播回复接收失败问题求助(Rust实现)

问题:UDP特定IP回复接收失败(广播回复正常)

发送UDP数据包功能正常,接收广播的回复也能正常工作,但接收发送至特定IP的数据包的回复时失败。通过tcpdump和Wireshark确认回复已发送到正确端口,但程序无法接收。

失败的代码示例

println!("sending local");
let socket = UdpSocket::bind("0.0.0.0:2012").expect("could not create socket");
socket
    .connect(self.ip.unwrap())
    .expect("could not connect to ics");
socket.send(command).unwrap();
let mut buf = vec![0; 1024];
while let Ok((n, addr)) = socket.recv_from(&mut buf) {
    println!("received {} bytes from {}", n, addr);
    buf.resize(n, 0);
}

正常工作的广播接收代码示例

let command = create_discover_command();
let socket = UdpSocket::bind("0.0.0.0:2012").expect("Could not create socket");
socket.set_broadcast(true).expect("Could not set broadcast");
socket
    .set_read_timeout(Some(Duration::new(5, 0)))
    .expect("Could not set timeout");

match socket.send_to(&command, "255.255.255.255:2012") {
    Ok(n) => {
        if n != command.len() {
            println!("Error");
        }
    }
    Err(e) => {
        println!("Error: {}", e);
    }
}
let mut buf = vec![0; 1024];
let mut address: Option<SocketAddr> = None;
while let Ok((n, addr)) = socket.recv_from(&mut buf) {
    println!("Received {} bytes from {}", n, addr);
    address = Some(addr);
    buf.resize(n, 0);
    match Message::try_from(buf.to_vec()) {
        Ok(mut message) => {
            if message.get_message_type() == MessageType::Acknowledge {
                break;
            }
            continue;
        }
        Err(_e) => continue;
    }
}

问题分析与解决方案

核心问题出在UDP socket的connect调用上:

  • UDP的connect并非建立实际连接,而是给socket添加了来源过滤规则,只会接收来自该特定IP和端口的数据包。
  • 如果对方回复的源端口和你connect时指定的端口不一致,recv_from会直接丢弃这些数据包,即使它们的目标端口正确。

解决方法:

  1. 移除connect调用,改用send_to直接发送到目标IP:端口,这样socket不会过滤来源,和广播场景保持一致。
  2. 若需验证回复来源,可在recv_from获取到addr后手动判断IP是否符合预期。

修改后的代码示例:

println!("sending local");
let socket = UdpSocket::bind("0.0.0.0:2012").expect("could not create socket");
// 用send_to替代connect+send
socket.send_to(command, &self.ip.unwrap()).unwrap();
let mut buf = vec![0; 1024];
while let Ok((n, addr)) = socket.recv_from(&mut buf) {
    println!("received {} bytes from {}", n, addr);
    // 可选:验证回复来源IP
    if addr.ip() == self.ip.unwrap().ip() {
        buf.resize(n, 0);
        // 后续处理逻辑...
    }
}

内容的提问来源于stack exchange,提问作者Jordy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 00:55:06