跳到主要内容

UdpSocket

搜索

结构体 UdpSocket 

Source
pub struct UdpSocket { /* private fields */ }
展开描述

UDP 套接字。

UDP is “connectionless”, unlike TCP. Meaning, regardless of what address you’ve bound to, a UdpSocket is free to communicate with many different remotes. 在 tokio 中 there are basically two main ways to use UdpSocket:

  • one to many: bind and use send_to and recv_from to communicate with many different addresses
  • one to one: connect and associate with a single address, using send and recv to communicate only with that remote address

此类型不提供 split 方法,因为可以通过将套接字包装到 Arc 中来实现同样的功能。请注意,共享 UdpSocket 并不需要 Mutex,使用 Arc<UdpSocket> 即可。这是因为所有方法都接受 &self 而不是 &mut self。一旦将其包装到 Arc 中,就可以对 Arc<UdpSocket> 调用 .clone() 来获得同一套接字的多个共享句柄。下面可以看到此类用法的示例。

§Streams

如果需要监听 UDP 并产生 Stream,可以参考 UdpFramed

§Example: one to many (bind)

使用 bind,我们可以创建一个简单的 echo 服务器,与多个不同的客户端互相收发数据:

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

#[tokio::main]
async fn main() -> io::Result<()> {
    let sock = UdpSocket::bind("0.0.0.0:8080").await?;
    let mut buf = [0; 1024];
    loop {
        let (len, addr) = sock.recv_from(&mut buf).await?;
        println!("{:?} bytes received from {:?}", len, addr);

        let len = sock.send_to(&buf[..len], addr).await?;
        println!("{:?} bytes sent", len);
    }
}

§Example: one to one (connect)

或者使用 connect,我们可以使用 sendrecv 与单个远端地址进行 echo 通信:

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

#[tokio::main]
async fn main() -> io::Result<()> {
    let sock = UdpSocket::bind("0.0.0.0:8080").await?;

    let remote_addr = "127.0.0.1:59611";
    sock.connect(remote_addr).await?;
    let mut buf = [0; 1024];
    loop {
        let len = sock.recv(&mut buf).await?;
        println!("{:?} bytes received from {:?}", len, remote_addr);

        let len = sock.send(&buf[..len]).await?;
        println!("{:?} bytes sent", len);
    }
}

§Example: Splitting with Arc

因为 send_torecv_from 接受 &self。所以使用 Arc<UdpSocket> 并向多个任务共享其引用是完全可以的。下面是一个支持并发发送/接收的类似“echo”示例:

use tokio::{net::UdpSocket, sync::mpsc};
use std::{io, net::SocketAddr, sync::Arc};

#[tokio::main]
async fn main() -> io::Result<()> {
    let sock = UdpSocket::bind("0.0.0.0:8080".parse::<SocketAddr>().unwrap()).await?;
    let r = Arc::new(sock);
    let s = r.clone();
    let (tx, mut rx) = mpsc::channel::<(Vec<u8>, SocketAddr)>(1_000);

    tokio::spawn(async move {
        while let Some((bytes, addr)) = rx.recv().await {
            let len = s.send_to(&bytes, &addr).await.unwrap();
            println!("{:?} bytes sent", len);
        }
    });

    let mut buf = [0; 1024];
    loop {
        let (len, addr) = r.recv_from(&mut buf).await?;
        println!("{:?} bytes received from {:?}", len, addr);
        tx.send((buf[..len].to_vec(), addr)).await.unwrap();
    }
}

实现§

Source§

impl UdpSocket

Source

pub async fn bind<A: ToSocketAddrs>(addr: A) -> Result<UdpSocket>

该函数将创建一个新的 UDP 套接字,并尝试将其绑定到所提供的 addr

使用端口号 0 进行绑定时,会要求操作系统为该监听器分配一个端口。分配的端口可以通过 local_addr 方法查询。

§Example
use tokio::net::UdpSocket;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    let sock = UdpSocket::bind("0.0.0.0:8080").await?;
    // use `sock`
    Ok(())
}
Source

pub fn from_std(socket: UdpSocket) -> Result<UdpSocket>

从之前绑定的 std::net::UdpSocket 创建新的 UdpSocket

该函数用于将标准库中的 UDP 套接字包装为 Tokio 的对应类型。

这可以与 socket2Socket 接口配合使用,以便在套接字移交之前对其进行配置,例如设置 reuse_address 等选项或绑定到多个地址。

§Notes

调用者负责确保套接字处于非阻塞模式。否则,套接字上的所有 I/O 操作都会阻塞线程,从而导致意外行为。可以使用 set_nonblocking 设置非阻塞模式。

传递一个阻塞模式的监听器始终是错误的,该情形下的行为可能会在未来发生变化。例如,可能会引发 panic。

§Panics

如果未设置线程局部运行时,该函数会引发 panic。

运行时通常会在从由 tokio 运行时驱动的 future 中调用此函数时隐式设置,否则可以使用 Runtime::enter 函数显式设置。

§Example
use tokio::net::UdpSocket;

let addr = "0.0.0.0:8080".parse::<SocketAddr>().unwrap();
let std_sock = std::net::UdpSocket::bind(addr)?;
std_sock.set_nonblocking(true)?;
let sock = UdpSocket::from_std(std_sock)?;
// use `sock`
Source

pub fn into_std(self) -> Result<UdpSocket>

tokio::net::UdpSocket 转换为 std::net::UdpSocket

返回的 std::net::UdpSocket 的非阻塞模式将被设置为 true。如有需要,可使用 set_nonblocking 修改阻塞模式。

§示例
use std::error::Error;

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let tokio_socket = tokio::net::UdpSocket::bind("127.0.0.1:0").await?;
    let std_socket = tokio_socket.into_std()?;
    std_socket.set_nonblocking(false)?;
    Ok(())
}
Source

pub fn local_addr(&self) -> Result<SocketAddr>

返回该套接字绑定的本地地址。

§Example
use tokio::net::UdpSocket;

let addr = "0.0.0.0:8080".parse::<SocketAddr>().unwrap();
let sock = UdpSocket::bind(addr).await?;
// the address the socket is bound to
let local_addr = sock.local_addr()?;
Source

pub fn peer_addr(&self) -> Result<SocketAddr>

返回该套接字连接到的远端对端的套接字地址。

§Example
use tokio::net::UdpSocket;

let addr = "0.0.0.0:8080".parse::<SocketAddr>().unwrap();
let peer = "127.0.0.1:11100".parse::<SocketAddr>().unwrap();
let sock = UdpSocket::bind(addr).await?;
sock.connect(peer).await?;
assert_eq!(peer, sock.peer_addr()?);
Source

pub async fn connect<A: ToSocketAddrs>(&self, addr: A) -> Result<()>

连接 UDP 套接字,为 send() 设置默认的目标地址,并限制通过 recv 接收的数据包仅来自 addr 指定的地址。

§Example
use tokio::net::UdpSocket;

let sock = UdpSocket::bind("0.0.0.0:8080".parse::<SocketAddr>().unwrap()).await?;

let remote_addr = "127.0.0.1:59600".parse::<SocketAddr>().unwrap();
sock.connect(remote_addr).await?;
let mut buf = [0u8; 32];
// recv from remote_addr
let len = sock.recv(&mut buf).await?;
// send to remote_addr
let _len = sock.send(&buf[..len]).await?;
Source

pub async fn ready(&self, interest: Interest) -> Result<Ready>

等待任意一个所请求的就绪状态。

该函数通常与 try_recv()try_send() 配合使用。它可以在不拆分套接字的情况下,让单个任务同时对该套接字进行 recv / send

函数可能在套接字尚未就绪时完成。这是误报情况,尝试进行操作时将返回 io::ErrorKind::WouldBlock。函数也可能返回空的 Ready 集合,因此应始终检查返回值,若请求的状态尚未设置则可能需要再次等待。

§Cancel safety

此方法可安全取消。一旦就绪事件发生,该方法将持续立即返回,直到就绪事件被尝试进行读取或写入(且失败返回 WouldBlockPoll::Pending)的操作消耗。

§示例

在不拆分的情况下,在同一任务上同时对套接字进行接收和发送。

use tokio::io::{self, Interest};
use tokio::net::UdpSocket;

#[tokio::main]
async fn main() -> io::Result<()> {
    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
    socket.connect("127.0.0.1:8081").await?;

    loop {
        let ready = socket.ready(Interest::READABLE | Interest::WRITABLE).await?;

        if ready.is_readable() {
            // The buffer is **not** included in the async task and will only exist
            // on the stack.
            let mut data = [0; 1024];
            match socket.try_recv(&mut data[..]) {
                Ok(n) => {
                    println!("received {:?}", &data[..n]);
                }
                // False-positive, continue
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
                Err(e) => {
                    return Err(e);
                }
            }
        }

        if ready.is_writable() {
            // Write some data
            match socket.try_send(b"hello world") {
                Ok(n) => {
                    println!("sent {} bytes", n);
                }
                // False-positive, continue
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
                Err(e) => {
                    return Err(e);
                }
            }
        }
    }
}
Source

pub async fn writable(&self) -> Result<()>

等待套接字变为可写。

该函数等同于 ready(Interest::WRITABLE),通常与 try_send()try_send_to() 配合使用。

函数可能在套接字尚未可写时完成。这是误报情况,尝试进行 try_send() 时将返回 io::ErrorKind::WouldBlock

§Cancel safety

此方法可安全取消。一旦就绪事件发生,该方法将持续立即返回,直到就绪事件被尝试进行写入(且失败返回 WouldBlockPoll::Pending)的操作消耗。

§示例
use tokio::net::UdpSocket;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Bind socket
    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
    socket.connect("127.0.0.1:8081").await?;

    loop {
        // Wait for the socket to be writable
        socket.writable().await?;

        // Try to send data, this may still fail with `WouldBlock`
        // if the readiness event is a false positive.
        match socket.try_send(b"hello world") {
            Ok(n) => {
                break;
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e);
            }
        }
    }

    Ok(())
}
Source

pub fn poll_send_ready(&self, cx: &mut Context<'_>) -> Poll<Result<()>>

Poll 写入/发送就绪状态。

如果 udp 流当前尚未准备好发送,此方法会存储提供的 ContextWaker 的一个克隆。当 udp 流变为可发送时,会在该 waker 上调用 Waker::wake

请注意,对于 poll_send_readypoll_send 的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。(不过,poll_recv_ready 仍保留一个独立的 waker。)

该函数用于不便通过 writable 创建并固定一个 future 的场景。在条件允许时,建议使用 writable,因为它支持同时从多个任务进行 poll。

§Return value

函数返回:

  • Poll::Pending if the udp stream is not ready for writing.
  • Poll::Ready(Ok(())) if the udp stream is ready for writing.
  • Poll::Ready(Err(e)) if an error is encountered.
§Errors

该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。

Source

pub async fn send(&self, buf: &[u8]) -> Result<usize>

通过套接字向其连接的远端地址发送数据。

connect 方法会将该套接字连接到远端地址。如果套接字尚未连接,此方法将失败。

如果远端地址已对之前发送的数据包回复了 ICMP Unreachable,此方法可能会因 ConnectionRefused 错误而失败。不过,这种行为取决于操作系统。

§Return

成功时返回发送的字节数,否则返回所遇到的错误。

§Cancel safety

此方法可安全取消。如果 send 作为 tokio::select! 语句中的事件,且某个其他分支先完成,则可以保证消息未被发送。

§示例
use tokio::io;
use tokio::net::UdpSocket;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Bind socket
    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
    socket.connect("127.0.0.1:8081").await?;

    // Send a message
    socket.send(b"hello world").await?;

    Ok(())
}
Source

pub fn poll_send(&self, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>>

尝试通过套接字向先前已 connect 的远端地址发送数据。

connect 方法会将该套接字连接到远端地址。如果套接字尚未连接,此方法将失败。

请注意,对于发送方向上 poll_* 方法的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。

§Return value

函数返回:

  • Poll::Pending if the socket is not available to write
  • Poll::Ready(Ok(n)) n is the number of bytes sent
  • Poll::Ready(Err(e)) if an error is encountered.
§Errors

该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。

Source

pub fn try_send(&self, buf: &[u8]) -> Result<usize>

尝试通过套接字向其连接的远端地址发送数据。

当套接字缓冲区已满时,返回 Err(io::ErrorKind::WouldBlock)。该函数通常与 writable() 配合使用。

§Returns

如果成功,则返回 Ok(n),其中 n 是已发送的字节数。如果套接字尚未准备好发送数据,则返回 Err(ErrorKind::WouldBlock)

§示例
use tokio::net::UdpSocket;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Bind a UDP socket
    let socket = UdpSocket::bind("127.0.0.1:8080").await?;

    // Connect to a peer
    socket.connect("127.0.0.1:8081").await?;

    loop {
        // Wait for the socket to be writable
        socket.writable().await?;

        // Try to send data, this may still fail with `WouldBlock`
        // if the readiness event is a false positive.
        match socket.try_send(b"hello world") {
            Ok(n) => {
                break;
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e);
            }
        }
    }

    Ok(())
}
Source

pub async fn readable(&self) -> Result<()>

等待套接字变为可读。

该函数等同于 ready(Interest::READABLE),通常与 try_recv() 配合使用。

函数可能在套接字尚未可读时完成。这是误报情况,尝试进行 try_recv() 时将返回 io::ErrorKind::WouldBlock

§Cancel safety

此方法可安全取消。一旦就绪事件发生,该方法将持续立即返回,直到就绪事件被尝试进行读取(且失败返回 WouldBlockPoll::Pending)的操作消耗。

§示例
use tokio::net::UdpSocket;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Connect to a peer
    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
    socket.connect("127.0.0.1:8081").await?;

    loop {
        // Wait for the socket to be readable
        socket.readable().await?;

        // The buffer is **not** included in the async task and will
        // only exist on the stack.
        let mut buf = [0; 1024];

        // Try to recv data, this may still fail with `WouldBlock`
        // if the readiness event is a false positive.
        match socket.try_recv(&mut buf) {
            Ok(n) => {
                println!("GOT {:?}", &buf[..n]);
                break;
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e);
            }
        }
    }

    Ok(())
}
Source

pub fn poll_recv_ready(&self, cx: &mut Context<'_>) -> Poll<Result<()>>

Poll 读取/接收就绪状态。

如果 udp 流当前尚未准备好接收,此方法会存储提供的 ContextWaker 的一个克隆。当 udp 套接字变为可读时,会在该 waker 上调用 Waker::wake

请注意,对于 poll_recv_readypoll_recvpoll_peek 的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。(不过,poll_send_ready 仍保留一个独立的 waker。)

该函数用于不便通过 readable 创建并固定一个 future 的场景。在条件允许时,建议使用 readable,因为它支持同时从多个任务进行 poll。

§Return value

函数返回:

  • Poll::Pending if the udp stream is not ready for reading.
  • Poll::Ready(Ok(())) if the udp stream is ready for reading.
  • Poll::Ready(Err(e)) if an error is encountered.
§Errors

该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。

Source

pub async fn recv(&self, buf: &mut [u8]) -> Result<usize>

从套接字所连接的远端地址接收单个数据报消息。成功时返回读取的字节数。

调用该函数时必须传入大小足够容纳消息字节的有效字节数组 buf。如果消息过长而无法放入所提供的缓冲区,则可能丢弃多余的字节。

connect 方法会将该套接字连接到远端地址。如果套接字尚未连接,此方法将失败。

§Cancel safety

此方法可安全取消。如果 recv 作为 tokio::select! 语句中的事件,且某个其他分支先完成,则可以保证此套接字未接收到任何消息。

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

#[tokio::main]
async fn main() -> io::Result<()> {
    // Bind socket
    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
    socket.connect("127.0.0.1:8081").await?;

    let mut buf = vec![0; 10];
    let n = socket.recv(&mut buf).await?;

    println!("received {} bytes {:?}", n, &buf[..n]);

    Ok(())
}
Source

pub fn poll_recv( &self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<()>>

尝试从该套接字所 connect 的远端地址接收单个数据报消息。

connect 方法会将该套接字连接到远端地址。如果套接字尚未连接,此方法会解析为错误。

请注意,对于 recv 方向上 poll_* 方法的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。

§Return value

函数返回:

  • Poll::Pending if the socket is not ready to read
  • Poll::Ready(Ok(())) reads data ReadBuf if the socket is ready
  • Poll::Ready(Err(e)) if an error is encountered.
§Errors

该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。

Source

pub fn try_recv(&self, buf: &mut [u8]) -> Result<usize>

尝试从套接字所连接的远端地址接收单个数据报消息。成功时返回读取的字节数。

调用此方法时必须传入大小足够容纳消息字节的有效字节数组 buf。如果消息过长而无法放入所提供的缓冲区,则可能丢弃多余的字节。

当没有待处理的数据时,返回 Err(io::ErrorKind::WouldBlock)。该函数通常与 readable() 配合使用。

§示例
use tokio::net::UdpSocket;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Connect to a peer
    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
    socket.connect("127.0.0.1:8081").await?;

    loop {
        // Wait for the socket to be readable
        socket.readable().await?;

        // The buffer is **not** included in the async task and will
        // only exist on the stack.
        let mut buf = [0; 1024];

        // Try to recv data, this may still fail with `WouldBlock`
        // if the readiness event is a false positive.
        match socket.try_recv(&mut buf) {
            Ok(n) => {
                println!("GOT {:?}", &buf[..n]);
                break;
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e);
            }
        }
    }

    Ok(())
}
Source

pub fn try_recv_buf<B: BufMut>(&self, buf: &mut B) -> Result<usize>

尝试从流接收数据到所提供的缓冲区中,推进缓冲区的内部游标,并返回已读取的字节数。

调用此方法时必须传入大小足够容纳消息字节的有效字节数组 buf。如果消息过长而无法放入所提供的缓冲区,则可能丢弃多余的字节。

即使 buf 未初始化,也可以使用此方法。

当没有待处理的数据时,返回 Err(io::ErrorKind::WouldBlock)。该函数通常与 readable() 配合使用。

§示例
use tokio::net::UdpSocket;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Connect to a peer
    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
    socket.connect("127.0.0.1:8081").await?;

    loop {
        // Wait for the socket to be readable
        socket.readable().await?;

        let mut buf = Vec::with_capacity(1024);

        // Try to recv data, this may still fail with `WouldBlock`
        // if the readiness event is a false positive.
        match socket.try_recv_buf(&mut buf) {
            Ok(n) => {
                println!("GOT {:?}", &buf[..n]);
                break;
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e);
            }
        }
    }

    Ok(())
}
Source

pub async fn recv_buf<B: BufMut>(&self, buf: &mut B) -> Result<usize>

从套接字所连接的远端地址接收单个数据报消息,并推进缓冲区的内部游标,返回读取的字节数。

调用此方法时必须传入大小足够容纳消息字节的有效字节数组 buf。如果消息过长而无法放入所提供的缓冲区,则可能丢弃多余的字节。

即使 buf 未初始化,也可以使用此方法。

§示例
use tokio::net::UdpSocket;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Connect to a peer
    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
    socket.connect("127.0.0.1:8081").await?;

    let mut buf = Vec::with_capacity(512);
    let len = socket.recv_buf(&mut buf).await?;

    println!("received {} bytes {:?}", len, &buf[..len]);

    Ok(())
}
Source

pub fn try_recv_buf_from<B: BufMut>( &self, buf: &mut B, ) -> Result<(usize, SocketAddr)>

尝试从套接字接收单个数据报消息。成功时返回读取的字节数及来源地址。

调用此方法时必须传入大小足够容纳消息字节的有效字节数组 buf。如果消息过长而无法放入所提供的缓冲区,则可能丢弃多余的字节。

即使 buf 未初始化,也可以使用此方法。

当没有待处理的数据时,返回 Err(io::ErrorKind::WouldBlock)。该函数通常与 readable() 配合使用。

§Notes

请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。

§示例
use tokio::net::UdpSocket;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Connect to a peer
    let socket = UdpSocket::bind("127.0.0.1:8080").await?;

    loop {
        // Wait for the socket to be readable
        socket.readable().await?;

        let mut buf = Vec::with_capacity(1024);

        // Try to recv data, this may still fail with `WouldBlock`
        // if the readiness event is a false positive.
        match socket.try_recv_buf_from(&mut buf) {
            Ok((n, _addr)) => {
                println!("GOT {:?}", &buf[..n]);
                break;
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e);
            }
        }
    }

    Ok(())
}
Source

pub async fn recv_buf_from<B: BufMut>( &self, buf: &mut B, ) -> Result<(usize, SocketAddr)>

从套接字接收单个数据报消息,并推进缓冲区的内部游标,返回读取的字节数及来源地址。

调用此方法时必须传入大小足够容纳消息字节的有效字节数组 buf。如果消息过长而无法放入所提供的缓冲区,则可能丢弃多余的字节。

即使 buf 未初始化,也可以使用此方法。

§Notes

请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。

§示例
use tokio::net::UdpSocket;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Connect to a peer
    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
    socket.connect("127.0.0.1:8081").await?;

    let mut buf = Vec::with_capacity(512);
    let (len, addr) = socket.recv_buf_from(&mut buf).await?;

    println!("received {:?} bytes from {:?}", len, addr);

    Ok(())
}
Source

pub async fn send_to<A: ToSocketAddrs>( &self, buf: &[u8], addr: A, ) -> Result<usize>

通过套接字向给定地址发送数据。成功时返回写入的字节数。

地址类型可以是 ToSocketAddrs trait 的任何实现者。具体示例请参阅其文档。

addr 可能会产生多个地址,但 send_to 只会将数据发送到 addr 产生的第一个地址。

当本地套接字的 IP 版本与 ToSocketAddrs 返回的版本不匹配时,将返回错误。

§Cancel safety

此方法可安全取消。如果 send_to 作为 tokio::select! 语句中的事件,且某个其他分支先完成,则可以保证消息未被发送。

§Example
use tokio::net::UdpSocket;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    let socket = UdpSocket::bind("127.0.0.1:8080").await?;
    let len = socket.send_to(b"hello world", "127.0.0.1:8081").await?;

    println!("Sent {} bytes", len);

    Ok(())
}
Source

pub fn poll_send_to( &self, cx: &mut Context<'_>, buf: &[u8], target: SocketAddr, ) -> Poll<Result<usize>>

尝试通过套接字向给定地址发送数据。

请注意,对于发送方向上 poll_* 方法的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。

§Return value

函数返回:

  • Poll::Pending if the socket is not ready to write
  • Poll::Ready(Ok(n)) n is the number of bytes sent.
  • Poll::Ready(Err(e)) if an error is encountered.
§Errors

该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。

Source

pub fn try_send_to(&self, buf: &[u8], target: SocketAddr) -> Result<usize>

尝试通过套接字向给定地址发送数据,但如果发送被阻塞,则会立即返回。

该函数通常与 writable() 配合使用。

§Returns

如果成功,则返回发送的字节数。

用户应确保在远端无法接收时正确处理 ErrorKind::WouldBlock。如果套接字的 IP 版本与 target 的版本不匹配,也可能发生错误。

§Example
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);
                break;
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                // Writable false positive.
                continue;
            }
            Err(e) => return Err(e.into()),
        }
    }

    Ok(())
}
Source

pub async fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>

从套接字接收单个数据报消息。成功时返回读取的字节数及来源地址。

调用该函数时必须传入大小足够容纳消息字节的有效字节数组 buf。如果消息过长而无法放入所提供的缓冲区,则可能丢弃多余的字节。

§Cancel safety

此方法可安全取消。如果 recv_from 作为 tokio::select! 语句中的事件,且某个其他分支先完成,则可以保证此套接字未接收到任何消息。

§Example
use tokio::net::UdpSocket;
use std::io;

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

    let mut buf = vec![0u8; 32];
    let (len, addr) = socket.recv_from(&mut buf).await?;

    println!("received {:?} bytes from {:?}", len, addr);

    Ok(())
}
§Notes

请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。

Source

pub fn poll_recv_from( &self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<SocketAddr>>

尝试从套接字接收单个数据报。

请注意,对于 recv 方向上 poll_* 方法的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。

§Return value

函数返回:

  • Poll::Pending if the socket is not ready to read
  • Poll::Ready(Ok(addr)) reads data from addr into ReadBuf if the socket is ready
  • Poll::Ready(Err(e)) if an error is encountered.
§Errors

该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。

§Notes

请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。

Source

pub fn try_recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>

尝试从套接字接收单个数据报消息。成功时返回读取的字节数及来源地址。

调用此方法时必须传入大小足够容纳消息字节的有效字节数组 buf。如果消息过长而无法放入所提供的缓冲区,则可能丢弃多余的字节。

当没有待处理的数据时,返回 Err(io::ErrorKind::WouldBlock)。该函数通常与 readable() 配合使用。

§Notes

请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。

§示例
use tokio::net::UdpSocket;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Connect to a peer
    let socket = UdpSocket::bind("127.0.0.1:8080").await?;

    loop {
        // Wait for the socket to be readable
        socket.readable().await?;

        // The buffer is **not** included in the async task and will
        // only exist on the stack.
        let mut buf = [0; 1024];

        // Try to recv data, this may still fail with `WouldBlock`
        // if the readiness event is a false positive.
        match socket.try_recv_from(&mut buf) {
            Ok((n, _addr)) => {
                println!("GOT {:?}", &buf[..n]);
                break;
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(e) => {
                return Err(e);
            }
        }
    }

    Ok(())
}
Source

pub fn try_io<R>( &self, interest: Interest, f: impl FnOnce() -> Result<R>, ) -> Result<R>

尝试使用用户提供的 IO 操作对套接字进行读写。

如果套接字就绪,则调用所提供的闭包。闭包应通过手动调用适当的系统调用来尝试对套接字执行 IO 操作。如果由于套接字实际上未就绪而导致操作失败,则闭包应返回 WouldBlock 错误,并清除就绪标志。然后 try_io 返回闭包的返回值。

如果套接字尚未就绪,则不会调用闭包,并返回 WouldBlock 错误。

闭包只有在执行了因套接字未就绪而失败的 IO 操作时,才应返回 WouldBlock 错误。在其他情况下返回 WouldBlock 错误会错误地清除就绪标志,可能导致套接字行为异常。

闭包不应使用 Tokio UdpSocket 类型上定义的任何方法来执行 IO 操作,因为这会干扰就绪标志,并可能导致套接字行为异常。

该方法不应与组合的 interest 一起使用。闭包应仅执行一种 IO 操作,因此不应需要多于一个就绪状态。如果使用组合的 interest 调用此方法,它可能会 panic 或永远睡眠。

通常,readable()writable()ready() 与该函数配合使用。

Source

pub async fn async_io<R>( &self, interest: Interest, f: impl FnMut() -> Result<R>, ) -> Result<R>

使用用户提供的 IO 操作对套接字进行读写。

等待套接字就绪,一旦就绪就调用所提供的闭包。闭包应通过手动调用适当的系统调用来尝试对套接字执行 IO 操作。如果由于套接字实际上未就绪而导致操作失败,则闭包应返回 WouldBlock 错误。此时就绪标志被清除,然后再次等待套接字就绪。该循环会反复进行,直到闭包返回 OkWouldBlock 以外的错误。

闭包只有在执行了因套接字未就绪而失败的 IO 操作时,才应返回 WouldBlock 错误。在其他情况下返回 WouldBlock 错误会错误地清除就绪标志,可能导致套接字行为异常。

闭包不应使用 Tokio UdpSocket 类型上定义的任何方法来执行 IO 操作,因为这会干扰就绪标志,并可能导致套接字行为异常。

该方法不应与组合的 interest 一起使用。闭包应仅执行一种 IO 操作,因此不应需要多于一个就绪状态。如果使用组合的 interest 调用此方法,它可能会 panic 或永远睡眠。

Source

pub async fn peek(&self, buf: &mut [u8]) -> Result<usize>

从已连接地址接收单个数据报,但不会从队列中移除。成功时返回读取的字节数以及数据来源。

§Notes

在 Windows 上,如果数据大于指定的缓冲区,则缓冲区将填充数据的第一部分,peek 会返回错误 WSAEMSGSIZE(10040)。多余的数据会丢失。请务必始终使用足够大的缓冲区来容纳最大的 UDP 数据包大小,最大可达 65536 字节。

如果你传入零大小的缓冲区,MacOS 将返回错误。

如果你只想了解队列头部数据的发送者,请尝试 peek_sender

请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。

§示例
use tokio::net::UdpSocket;
use std::io;

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

    let mut buf = vec![0u8; 32];
    let len = socket.peek(&mut buf).await?;

    println!("peeked {:?} bytes", len);

    Ok(())
}
Source

pub fn poll_peek( &self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<()>>

从已连接地址接收数据,但不会从输入队列中移除。

§Notes

请注意,对于 recv 方向上 poll_* 方法的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。

在 Windows 上,如果数据大于指定的缓冲区,则缓冲区将填充数据的第一部分,peek 会返回错误 WSAEMSGSIZE(10040)。多余的数据会丢失。请务必始终使用足够大的缓冲区来容纳最大的 UDP 数据包大小,最大可达 65536 字节。

如果你传入零大小的缓冲区,MacOS 将返回错误。

如果你只想了解队列头部数据的发送者,请尝试 poll_peek_sender

请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。

§Return value

函数返回:

  • Poll::Pending if the socket is not ready to read
  • Poll::Ready(Ok(())) reads data into ReadBuf if the socket is ready
  • Poll::Ready(Err(e)) if an error is encountered.
§Errors

该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。

Source

pub fn try_peek(&self, buf: &mut [u8]) -> Result<usize>

尝试从已连接地址接收数据,但不会从输入队列中移除。成功时返回读取的字节数。

当没有待处理的数据时,返回 Err(io::ErrorKind::WouldBlock)。该函数通常与 readable() 配合使用。

§Notes

在 Windows 上,如果数据大于指定的缓冲区,则缓冲区将填充数据的第一部分,peek 会返回错误 WSAEMSGSIZE(10040)。多余的数据会丢失。请务必始终使用足够大的缓冲区来容纳最大的 UDP 数据包大小,最大可达 65536 字节。

如果你传入零大小的缓冲区,MacOS 将返回错误。

如果你只想了解队列头部数据的发送者,请尝试 try_peek_sender

请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。

Source

pub async fn peek_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>

从套接字接收数据,但不会从输入队列中移除。成功时返回读取的字节数以及数据来源地址。

§Notes

在 Windows 上,如果数据大于指定的缓冲区,则缓冲区将填充数据的第一部分,peek_from 会返回错误 WSAEMSGSIZE(10040)。多余的数据会丢失。请务必始终使用足够大的缓冲区来容纳最大的 UDP 数据包大小,最大可达 65536 字节。

如果你传入零大小的缓冲区,MacOS 将返回错误。

如果你只想了解队列头部数据的发送者,请尝试 peek_sender

请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。

§示例
use tokio::net::UdpSocket;
use std::io;

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

    let mut buf = vec![0u8; 32];
    let (len, addr) = socket.peek_from(&mut buf).await?;

    println!("peeked {:?} bytes from {:?}", len, addr);

    Ok(())
}
Source

pub fn poll_peek_from( &self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<SocketAddr>>

从套接字接收数据,但不会从输入队列中移除。成功时返回数据报的发送地址。

§Notes

请注意,对于 recv 方向上 poll_* 方法的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。

在 Windows 上,如果数据大于指定的缓冲区,则缓冲区将填充数据的第一部分,peek 会返回错误 WSAEMSGSIZE(10040)。多余的数据会丢失。请务必始终使用足够大的缓冲区来容纳最大的 UDP 数据包大小,最大可达 65536 字节。

如果你传入零大小的缓冲区,MacOS 将返回错误。

如果你只想了解队列头部数据的发送者,请尝试 poll_peek_sender

请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。

§Return value

函数返回:

  • Poll::Pending if the socket is not ready to read
  • Poll::Ready(Ok(addr)) reads data from addr into ReadBuf if the socket is ready
  • Poll::Ready(Err(e)) if an error is encountered.
§Errors

该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。

Source

pub fn try_peek_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>

尝试从套接字接收数据,但不会从输入队列中移除。成功时返回读取的字节数以及数据报的发送地址。

当没有待处理的数据时,返回 Err(io::ErrorKind::WouldBlock)。该函数通常与 readable() 配合使用。

§Notes

在 Windows 上,如果数据大于指定的缓冲区,则缓冲区将填充数据的第一部分,peek 会返回错误 WSAEMSGSIZE(10040)。多余的数据会丢失。请务必始终使用足够大的缓冲区来容纳最大的 UDP 数据包大小,最大可达 65536 字节。

如果你传入零大小的缓冲区,MacOS 将返回错误。

如果你只想了解队列头部数据的发送者,请尝试 try_peek_sender

请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。

Source

pub async fn peek_sender(&self) -> Result<SocketAddr>

检索输入队列头部数据的发送者,如果队列为空则等待。

这相当于使用零大小的缓冲区调用 peek_from,但会抑制 Windows 上的 WSAEMSGSIZE 错误以及 macOS 上的“invalid argument”错误。

请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。

Source

pub fn poll_peek_sender(&self, cx: &mut Context<'_>) -> Poll<Result<SocketAddr>>

检索输入队列头部数据的发送者,如果队列为空则调度一次唤醒。

这相当于使用零大小的缓冲区调用 poll_peek_from,但会抑制 Windows 上的 WSAEMSGSIZE 错误以及 macOS 上的“invalid argument”错误。

§Notes

请注意,对于 recv 方向上 poll_* 方法的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。

请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。

Source

pub fn try_peek_sender(&self) -> Result<SocketAddr>

尝试检索输入队列头部数据的发送者。

当没有待处理的数据时,返回 Err(io::ErrorKind::WouldBlock)。该函数通常与 readable() 配合使用。

请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。

Source

pub fn broadcast(&self) -> Result<bool>

获取该套接字的 SO_BROADCAST 选项值。

有关此选项的更多信息,请参见 set_broadcast

Source

pub fn set_broadcast(&self, on: bool) -> Result<()>

设置该套接字的 SO_BROADCAST 选项值。

启用后,此套接字可以向广播地址发送数据包。

Source

pub fn multicast_loop_v4(&self) -> Result<bool>

获取该套接字的 IP_MULTICAST_LOOP 选项值。

有关此选项的更多信息,请参见 set_multicast_loop_v4

Source

pub fn set_multicast_loop_v4(&self, on: bool) -> Result<()>

设置该套接字的 IP_MULTICAST_LOOP 选项值。

如果启用,多播数据包将被回环到本地套接字。

§Note

这对 IPv6 套接字可能没有任何效果。

Source

pub fn multicast_ttl_v4(&self) -> Result<u32>

获取该套接字的 IP_MULTICAST_TTL 选项值。

有关此选项的更多信息,请参见 set_multicast_ttl_v4

Source

pub fn set_multicast_ttl_v4(&self, ttl: u32) -> Result<()>

设置该套接字的 IP_MULTICAST_TTL 选项值。

指示此套接字对外发送多播数据包的生存时间值。默认值为 1,这意味着多播数据包不会离开本地网络,除非显式请求。

§Note

这对 IPv6 套接字可能没有任何效果。

Source

pub fn multicast_loop_v6(&self) -> Result<bool>

获取该套接字的 IPV6_MULTICAST_LOOP 选项值。

有关此选项的更多信息,请参见 set_multicast_loop_v6

Source

pub fn set_multicast_loop_v6(&self, on: bool) -> Result<()>

设置该套接字的 IPV6_MULTICAST_LOOP 选项值。

控制此套接字是否能看到自身发送的多播数据包。

§Note

这对 IPv4 套接字可能没有任何效果。

Source

pub fn ttl(&self) -> Result<u32>

获取该套接字的 IP_TTL 选项值。

有关此选项的更多信息,请参见 set_ttl

§示例
use tokio::net::UdpSocket;

let sock = UdpSocket::bind("127.0.0.1:8080").await?;

println!("{:?}", sock.ttl()?);
Source

pub fn set_ttl(&self, ttl: u32) -> Result<()>

为该套接字设置 IP_TTL 选项的值。

此值设置了从该套接字发出的每个数据包中使用的生存时间字段。

§示例
use tokio::net::UdpSocket;

let sock = UdpSocket::bind("127.0.0.1:8080").await?;
sock.set_ttl(60)?;
Source

pub fn tos_v4(&self) -> Result<u32>

获取该套接字的 IP_TOS 选项值。

有关此选项的更多信息,请参见 set_tos_v4

Source

pub fn set_tos_v4(&self, tos: u32) -> Result<()>

为该套接字设置 IP_TOS 选项的值。

此值设置了从该套接字发出的每个数据包中使用的服务类型字段。

§Note
Source

pub fn join_multicast_v4( &self, multiaddr: Ipv4Addr, interface: Ipv4Addr, ) -> Result<()>

执行 IP_ADD_MEMBERSHIP 类型的操作。

该函数为该套接字指定一个新的多播组以加入。地址必须是有效的多播地址,interface 是系统应通过其加入多播组的本地接口的地址。如果它等于 INADDR_ANY,则由系统选择合适的接口。

Source

pub fn join_multicast_v6( &self, multiaddr: &Ipv6Addr, interface: u32, ) -> Result<()>

执行 IPV6_ADD_MEMBERSHIP 类型的操作。

该函数为该套接字指定一个新的多播组以加入。地址必须是有效的多播地址,interface 是要加入/离开的接口的索引(或 0,表示任意接口)。

Source

pub fn leave_multicast_v4( &self, multiaddr: Ipv4Addr, interface: Ipv4Addr, ) -> Result<()>

执行 IP_DROP_MEMBERSHIP 类型的操作。

有关此选项的更多信息,请参见 join_multicast_v4

Source

pub fn leave_multicast_v6( &self, multiaddr: &Ipv6Addr, interface: u32, ) -> Result<()>

执行 IPV6_DROP_MEMBERSHIP 类型的操作。

有关此选项的更多信息,请参见 join_multicast_v6

Source

pub fn take_error(&self) -> Result<Option<Error>>

返回 SO_ERROR 选项的值。

§示例
use tokio::net::UdpSocket;
use std::io;

#[tokio::main]
async fn main() -> io::Result<()> {
    // Create a socket
    let socket = UdpSocket::bind("0.0.0.0:8080").await?;

    if let Ok(Some(err)) = socket.take_error() {
        println!("Got error: {:?}", err);
    }

    Ok(())
}

Trait 实现§

Source§

impl AsRawSocket for UdpSocket

Available on docsrs, or Windows only.
Source§

fn as_raw_socket(&self) -> RawSocket

Extracts the raw socket. 更多信息
Source§

impl AsSocket for UdpSocket

Available on docsrs, or Windows only.
Source§

fn as_socket(&self) -> BorrowedSocket<'_>

借用此套接字。
Source§

impl Debug for UdpSocket

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

使用给定的格式化器格式化此值。 更多信息
Source§

impl TryFrom<UdpSocket> for UdpSocket

Source§

fn try_from(stream: UdpSocket) -> Result<Self, Self::Error>

消耗流,返回 tokio 的 I/O 对象。

这等同于 UdpSocket::from_std(stream)

Source§

type Error = Error

转换出错时返回的类型。

自动 Trait 实现§

Blanket 实现§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. 更多信息
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. 更多信息
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. 更多信息
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

原样返回传入的参数。

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

调用 U::from(self)

也就是说,此转换的具体行为取决于 From<T> for U 的实现方式。

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

转换出错时返回的类型。
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

执行转换。
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

转换出错时返回的类型。
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

执行转换。