Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Networking 如何广播UDP数据报并在Rust中接收响应?_Networking_Rust_Udp_Ip - Fatal编程技术网

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

Networking 如何广播UDP数据报并在Rust中接收响应?,networking,rust,udp,ip,Networking,Rust,Udp,Ip,我尝试在Rust中实现VXI11协议(与示波器、电源等仪器通信),并且成功发送广播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.2

我尝试在Rust中实现VXI11协议(与示波器、电源等仪器通信),并且成功发送广播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
    }
我还知道远程主机正在响应,因为我可以在tcpdump中看到它。然而,锈代码并没有收到响应。有人知道为什么会这样吗

$ 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
。如果不知道远程地址,则可以根本避免调用
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
}
let socket:UdpSocket=UdpSocket::bind(“0.0.0.0:0”)?;
socket.set_read_timeout(一些(持续时间::new(5,0))?;
插座。设置广播(真)?;
普林顿!(“在端口{}上连接”,端口);
普林顿!((“广播:{:?}”,socket.Broadcast());
普林顿!((“超时:{:?}”,socket.read_Timeout());
让我们调用:Vec=self.packer.get_buf()?;
普林顿!(“发送调用,{}字节”,call.len());
匹配self.socket.send(&call){
Ok(n)=>{
如果n!=调用.len(){
返回Err(Error::new(ErrorKind::Other,“发送的字节数错误”))
}
否则{
//不执行任何操作,因为我们发送了预期发送的字节数
}
},
Err(e)=>返回Err(e),
}
普林顿!(“等待答复…”)self.recv_buff是一个[u8;8092]
而让Ok((n,addr))=self.socket.recv_from(&mut self.recv_buff){
println!(“{:?}”的{}字节响应,n,addr);
//与问题不直接相关的剩余代码
}

使用广播是上个世纪基本上被弃用的技术,它不能移植到IPv6,因为IPv6中没有广播。现代的方法是使用多播。看。是的,我的理解是VXI11无论如何都是一个较旧的协议,可能任何取代它的协议都会反对UDP广播。然而,我仍然有同样的问题。我可以看到tcpdump中的UDP数据包被发送到一个我应该绑定到的套接字,但它们没有出现。那些最初由UDP广播触发的传输是另一个问题。是的,这看起来和我下面接受的答案非常相似。谢谢这个答案稍加修改就解决了我的问题。我需要使用self.socket.send_to(…)而不是self.socket.send(…)。否则您将得到
错误:Os{code:89,种类:Other,消息:“需要目标地址”}
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
}