networking - 如何在 Rust 中广播 UDP 数据报并接收响应?

标签 networking rust udp ip

这个问题在这里已经有了答案:





UDP messages from C++ are not received by Rust

(1 个回答)


2年前关闭。




我正在尝试在 Rust 中实现 VXI11 协议(protocol)(与示波器、电源等仪器进行通信)并且我成功地发送了广播 UDP 消息,但没有收到响应。这是我用来设置 UDP 套接字的代码:

    let socket:UdpSocket = UdpSocket::bind("0.0.0.0:0")?;
    socket.set_read_timeout(Some(Duration::new(5, 0)))?;
    socket.set_broadcast(true)?;
    socket.connect(("255.255.255.255", port))?;
    println!("Connected on port {}", port);
    println!("Broadcast: {:?}", socket.broadcast());
    println!("Timeout: {:?}", socket.read_timeout());

我还在绑定(bind)调用中尝试了“255.255.255.255:0”和“192.168.2.255:0”,但没有成功。这是我用来接收响应的代码。
    let call:Vec<u8> = self.packer.get_buf()?;
    println!("Sending call, {} bytes", call.len());
    match self.socket.send(&call) {
        Ok(n) => {
            if n != call.len() {
                return Err(Error::new(ErrorKind::Other, "Sent the wrong number of bytes"))
            }
            else {
                // Do nothing because we sent the number of bytes we expected to send
            }
        },
        Err(e) => return Err(e),
    }

    println!("Awaiting responses...");   // self.recv_buff is a [u8; 8092]
    while let Ok((n, addr)) = self.socket.recv_from(&mut self.recv_buff) {
        println!("{} bytes response from {:?}", n, addr);
        // Remaining code not directly relevant to the question
    }

这是 STDOUT 输出:
Connected on port 111
Broadcast: Ok(true)
Timeout: Ok(Some(5s))
Sending call, 56 bytes
Awaiting responses...

我也知道远程主机正在响应,因为我可以在 tcpdump 中看到它。然而,Rust 代码只是没有收到响应。有人知道为什么会这样吗?
$ sudo tcpdump 'udp port 111'
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlo1, link-type EN10MB (Ethernet), capture size 262144 bytes
11:00:54.094534 IP deathStar.51499 > 255.255.255.255.sunrpc: UDP, length 56
11:00:54.100199 IP 192.168.2.4.sunrpc > deathStar.51499: UDP, length 28
11:00:54.100755 IP 192.168.2.3.sunrpc > deathStar.51499: UDP, length 28

最佳答案

TL;DR 删除 UdpSocket::connect打电话,然后再试一次。届时它将起作用。

看起来像 UdpSocket::connect 是根本原因。基于documentation , UdpSocket::connect如果套接字必须处理来自具体远程地址的数据,则应该使用。如果不知道远程地址,则可以避免 connect打电话。没有 connect调用,套接字将接收来自任何远程地址的数据。

let socket:UdpSocket = UdpSocket::bind("0.0.0.0:0")?;
socket.set_read_timeout(Some(Duration::new(5, 0)))?;
socket.set_broadcast(true)?;
println!("Connected on port {}", port);
println!("Broadcast: {:?}", socket.broadcast());
println!("Timeout: {:?}", socket.read_timeout());

let call:Vec<u8> = self.packer.get_buf()?;
println!("Sending call, {} bytes", call.len());
match self.socket.send(&call) {
    Ok(n) => {
        if n != call.len() {
            return Err(Error::new(ErrorKind::Other, "Sent the wrong number of bytes"))
        }
        else {
            // Do nothing because we sent the number of bytes we expected to send
        }
    },
    Err(e) => return Err(e),
}

println!("Awaiting responses...");   // self.recv_buff is a [u8; 8092]
while let Ok((n, addr)) = self.socket.recv_from(&mut self.recv_buff) {
    println!("{} bytes response from {:?}", n, addr);
    // Remaining code not directly relevant to the question
}

关于networking - 如何在 Rust 中广播 UDP 数据报并接收响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61045602/

相关文章:

c# - 通过 HttpWebRequest 传递二进制数据

android - 替代 NetworkInterface.getHardwareAddress()?

使用 headless Chrome (Rust)进行网页抓取,点击似乎不起作用

rust - 如何使 Rust 函数 `zip_map` 采用二元函数而不是以二元组作为参数的一元函数?

asynchronous - Rust 显示预期的特征对象 `dyn Future` ,在将函数作为参数传递时发现不透明类型

network-programming - UDP sendto() 何时阻塞?

linux - PulledPork 无法找到 Snort 二进制文件

ios - 如何取消 Objective-C 中的异步 HTTP 请求?

go - ReadMsgUDP中返回参数 "flags"是什么意思?

networking - netstat -na : udp and state established?