跳到主要内容

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,我们可以使用 send 和 recv 与单个远端地址进行 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_to 和 recv_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 的对应类型。

这可以与 socket2 的 Socket 接口配合使用,以便在套接字移交之前对其进行配置,例如设置 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

此方法可安全取消。一旦就绪事件发生,该方法将持续立即返回,直到就绪事件被尝试进行读取或写入(且失败返回 WouldBlock 或 Poll::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

此方法可安全取消。一旦就绪事件发生,该方法将持续立即返回,直到就绪事件被尝试进行写入(且失败返回 WouldBlock 或 Poll::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 流当前尚未准备好发送,此方法会存储提供的 Context 中 Waker 的一个克隆。当 udp 流变为可发送时,会在该 waker 上调用 Waker::wake。

请注意,对于 poll_send_ready 或 poll_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

此方法可安全取消。一旦就绪事件发生,该方法将持续立即返回,直到就绪事件被尝试进行读取(且失败返回 WouldBlock 或 Poll::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 流当前尚未准备好接收,此方法会存储提供的 Context 中 Waker 的一个克隆。当 udp 套接字变为可读时,会在该 waker 上调用 Waker::wake。

请注意,对于 poll_recv_ready、poll_recv 或 poll_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 错误。此时就绪标志被清除,然后再次等待套接字就绪。该循环会反复进行,直到闭包返回 Ok 或 WouldBlock 以外的错误。

闭包只有在执行了因套接字未就绪而失败的 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>

执行转换。