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会直接丢弃这些数据包,即使它们的目标端口正确。
解决方法:
- 移除
connect调用,改用send_to直接发送到目标IP:端口,这样socket不会过滤来源,和广播场景保持一致。 - 若需验证回复来源,可在
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
相关产品推荐
相关产品推荐

