rust 如何检测套接字没有监听udp

lbsnaicq  于 2023-11-19  发布在  其他
关注(0)|答案(1)|浏览(103)

我正在尝试通过udp发送数据。它可以工作,但是即使目标套接字不存在,我也没有收到任何错误。有什么方法可以检测到套接字没有监听吗?
我正在使用这段代码。没有任何东西在端口8081上侦听,但我根本没有收到错误。相反,如果我从python上做同样的事情,我会收到错误消息“Connection refused”。

use tokio::net::UdpSocket;
use std::error::Error;
use std::io;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let socket = UdpSocket::bind("127.0.0.1:8080").await?;

    let dst = "127.0.0.1:8081".parse()?;

    loop {
        socket.writable().await?;

        match socket.try_send_to(&b"hello world"[..], dst) {
            Ok(sent) => {
                println!("sent {} bytes", sent);
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                // Writable false positive.
                println!("{e}");
            }
            Err(e) => return Err(e.into()),
        }
    }

    Ok(())
}

字符串
更新:根据Steffen下面的评论更新了代码。仍然没有错误发送udp消息到非侦听端口。

3htmauhk

3htmauhk1#

UDP没有TCP那样的真实的连接,即在发送任何数据之前建立初始连接。因此,为了检测目的地是否有UDP侦听器,需要发送一个数据包,然后检查数据包是否被接收。
UDP对此有一种机制:如果接收系统收到一个没有监听器的IP端口的UDP数据包,它将发送一个无法到达的HTTP消息(对于IPv4,类似于IPv6的消息)。假设这个HTTP数据包实际上到达了原始发送者(即没有防火墙阻止它),那么套接字将被标记为这个错误,并且错误将在下一个套接字操作中传递,就像另一个发送一样。
但是,这仅在套接字连接时才成立,即在您的示例中调用socket.connect("127.0.0.1:8081")(并且使用socket.try_send代替socket.try_send_to)。对于未连接的套接字(如您的情况),错误不会被传递,因为它不匹配特定的连接(因为没有连接)。
如果我从python做同样的事情,我会得到错误消息“连接拒绝”
如果你在Python中使用一个未连接的套接字,你也不会得到错误。如果你使用一个连接的套接字,你会得到错误。所以很可能你的Python代码没有做你的Rust代码所做的“相同”。
(from注解)在python中,我确实绑定到了socket,然后sendall。
sendall没有目的地参数,所以它需要一个连接的套接字。因此错误被传递到连接的套接字。

相关问题