我正在尝试接收对 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,
}
}
除了在套接字上设置广播和发送回复的源端口外,我看不出这两个函数有什么区别。然而,两个回复的目标端口是相同的。
似乎在 Rust 中使用 udp 套接字连接到一个 ip 和端口只会听取来自该特定 ip 和端口的回复。为了防止这种情况发生,我将代码更改为不连接到特定的 ip,而是像这样使用 send_to 函数。
let socket = UdpSocket::bind("0.0.0.0:2012").expect("could not create socket");
socket.send_to(command, self.ip.unwrap()).unwrap();
Jordys 的回答 几乎涵盖了问题所在,我找到了另一个解决方案,如果您仍然想使用
connect
但仍然需要收听任何可以通过“连接”再次“断开连接”的来源"0.0.0.0:0"
:
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();
socket.connect("0.0.0.0:0").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);
}