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:
bindand usesend_toandrecv_fromto communicate with many different addresses - one to one:
connectand associate with a single address, usingsendandrecvto 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
impl UdpSocket
Sourcepub async fn bind<A: ToSocketAddrs>(addr: A) -> Result<UdpSocket>
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(())
}Sourcepub fn from_std(socket: UdpSocket) -> Result<UdpSocket>
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`Sourcepub fn into_std(self) -> Result<UdpSocket>
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(())
}Sourcepub fn local_addr(&self) -> Result<SocketAddr>
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()?;Sourcepub fn peer_addr(&self) -> Result<SocketAddr>
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()?);Sourcepub async fn connect<A: ToSocketAddrs>(&self, addr: A) -> Result<()>
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?;Sourcepub async fn ready(&self, interest: Interest) -> Result<Ready>
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);
}
}
}
}
}Sourcepub async fn writable(&self) -> Result<()>
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(())
}Sourcepub fn poll_send_ready(&self, cx: &mut Context<'_>) -> Poll<Result<()>>
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::Pendingif 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 错误。
Sourcepub async fn send(&self, buf: &[u8]) -> Result<usize>
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(())
}Sourcepub fn poll_send(&self, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>>
pub fn poll_send(&self, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>>
尝试通过套接字向先前已 connect 的远端地址发送数据。
connect 方法会将该套接字连接到远端地址。如果套接字尚未连接,此方法将失败。
请注意,对于发送方向上 poll_* 方法的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。
§Return value
函数返回:
Poll::Pendingif the socket is not available to writePoll::Ready(Ok(n))nis the number of bytes sentPoll::Ready(Err(e))if an error is encountered.
§Errors
该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。
Sourcepub fn try_send(&self, buf: &[u8]) -> Result<usize>
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(())
}Sourcepub async fn readable(&self) -> Result<()>
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(())
}Sourcepub fn poll_recv_ready(&self, cx: &mut Context<'_>) -> Poll<Result<()>>
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::Pendingif 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 错误。
Sourcepub async fn recv(&self, buf: &mut [u8]) -> Result<usize>
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(())
}Sourcepub fn poll_recv(
&self,
cx: &mut Context<'_>,
buf: &mut ReadBuf<'_>,
) -> Poll<Result<()>>
pub fn poll_recv( &self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<()>>
尝试从该套接字所 connect 的远端地址接收单个数据报消息。
connect 方法会将该套接字连接到远端地址。如果套接字尚未连接,此方法会解析为错误。
请注意,对于 recv 方向上 poll_* 方法的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。
§Return value
函数返回:
Poll::Pendingif the socket is not ready to readPoll::Ready(Ok(()))reads dataReadBufif the socket is readyPoll::Ready(Err(e))if an error is encountered.
§Errors
该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。
Sourcepub fn try_recv(&self, buf: &mut [u8]) -> Result<usize>
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(())
}Sourcepub fn try_recv_buf<B: BufMut>(&self, buf: &mut B) -> Result<usize>
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(())
}Sourcepub async fn recv_buf<B: BufMut>(&self, buf: &mut B) -> Result<usize>
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(())
}Sourcepub fn try_recv_buf_from<B: BufMut>(
&self,
buf: &mut B,
) -> Result<(usize, SocketAddr)>
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(())
}Sourcepub async fn recv_buf_from<B: BufMut>(
&self,
buf: &mut B,
) -> Result<(usize, SocketAddr)>
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(())
}Sourcepub async fn send_to<A: ToSocketAddrs>(
&self,
buf: &[u8],
addr: A,
) -> Result<usize>
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(())
}Sourcepub fn poll_send_to(
&self,
cx: &mut Context<'_>,
buf: &[u8],
target: SocketAddr,
) -> Poll<Result<usize>>
pub fn poll_send_to( &self, cx: &mut Context<'_>, buf: &[u8], target: SocketAddr, ) -> Poll<Result<usize>>
Sourcepub fn try_send_to(&self, buf: &[u8], target: SocketAddr) -> Result<usize>
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(())
}Sourcepub async fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>
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 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。
Sourcepub fn poll_recv_from(
&self,
cx: &mut Context<'_>,
buf: &mut ReadBuf<'_>,
) -> Poll<Result<SocketAddr>>
pub fn poll_recv_from( &self, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>, ) -> Poll<Result<SocketAddr>>
尝试从套接字接收单个数据报。
请注意,对于 recv 方向上 poll_* 方法的多次调用,仅会调度传递给最近一次调用的 Context 中的 Waker 接收唤醒。
§Return value
函数返回:
Poll::Pendingif the socket is not ready to readPoll::Ready(Ok(addr))reads data fromaddrintoReadBufif the socket is readyPoll::Ready(Err(e))if an error is encountered.
§Errors
该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。
§Notes
请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。
Sourcepub fn try_recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>
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(())
}Sourcepub fn try_io<R>(
&self,
interest: Interest,
f: impl FnOnce() -> Result<R>,
) -> Result<R>
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() 与该函数配合使用。
Sourcepub async fn async_io<R>(
&self,
interest: Interest,
f: impl FnMut() -> Result<R>,
) -> Result<R>
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 或永远睡眠。
Sourcepub async fn peek(&self, buf: &mut [u8]) -> Result<usize>
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(())
}Sourcepub fn poll_peek(
&self,
cx: &mut Context<'_>,
buf: &mut ReadBuf<'_>,
) -> Poll<Result<()>>
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::Pendingif the socket is not ready to readPoll::Ready(Ok(()))reads data intoReadBufif the socket is readyPoll::Ready(Err(e))if an error is encountered.
§Errors
该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。
Sourcepub fn try_peek(&self, buf: &mut [u8]) -> Result<usize>
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 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。
Sourcepub async fn peek_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>
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(())
}Sourcepub fn poll_peek_from(
&self,
cx: &mut Context<'_>,
buf: &mut ReadBuf<'_>,
) -> Poll<Result<SocketAddr>>
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::Pendingif the socket is not ready to readPoll::Ready(Ok(addr))reads data fromaddrintoReadBufif the socket is readyPoll::Ready(Err(e))if an error is encountered.
§Errors
该函数可能会遇到除 WouldBlock 之外的任何标准 I/O 错误。
Sourcepub fn try_peek_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>
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 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。
Sourcepub async fn peek_sender(&self) -> Result<SocketAddr>
pub async fn peek_sender(&self) -> Result<SocketAddr>
Sourcepub fn poll_peek_sender(&self, cx: &mut Context<'_>) -> Poll<Result<SocketAddr>>
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 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。
Sourcepub fn try_peek_sender(&self) -> Result<SocketAddr>
pub fn try_peek_sender(&self) -> Result<SocketAddr>
尝试检索输入队列头部数据的发送者。
当没有待处理的数据时,返回 Err(io::ErrorKind::WouldBlock)。该函数通常与 readable() 配合使用。
请注意,套接字地址不能被隐式信任,因为在 数据包注入攻击 中以伪造的源地址发送 UDP 数据报相对容易。由于 UDP 是无状态的且不验证数据包的来源,攻击者无需能够拦截流量即可进行干扰。在设计应用层协议时,请务必了解这一点。
Sourcepub fn broadcast(&self) -> Result<bool>
pub fn broadcast(&self) -> Result<bool>
获取该套接字的 SO_BROADCAST 选项值。
有关此选项的更多信息,请参见 set_broadcast。
Sourcepub fn set_broadcast(&self, on: bool) -> Result<()>
pub fn set_broadcast(&self, on: bool) -> Result<()>
设置该套接字的 SO_BROADCAST 选项值。
启用后,此套接字可以向广播地址发送数据包。
Sourcepub fn multicast_loop_v4(&self) -> Result<bool>
pub fn multicast_loop_v4(&self) -> Result<bool>
获取该套接字的 IP_MULTICAST_LOOP 选项值。
有关此选项的更多信息,请参见 set_multicast_loop_v4。
Sourcepub fn set_multicast_loop_v4(&self, on: bool) -> Result<()>
pub fn set_multicast_loop_v4(&self, on: bool) -> Result<()>
Sourcepub fn multicast_ttl_v4(&self) -> Result<u32>
pub fn multicast_ttl_v4(&self) -> Result<u32>
获取该套接字的 IP_MULTICAST_TTL 选项值。
有关此选项的更多信息,请参见 set_multicast_ttl_v4。
Sourcepub fn set_multicast_ttl_v4(&self, ttl: u32) -> Result<()>
pub fn set_multicast_ttl_v4(&self, ttl: u32) -> Result<()>
设置该套接字的 IP_MULTICAST_TTL 选项值。
指示此套接字对外发送多播数据包的生存时间值。默认值为 1,这意味着多播数据包不会离开本地网络,除非显式请求。
§Note
这对 IPv6 套接字可能没有任何效果。
Sourcepub fn multicast_loop_v6(&self) -> Result<bool>
pub fn multicast_loop_v6(&self) -> Result<bool>
获取该套接字的 IPV6_MULTICAST_LOOP 选项值。
有关此选项的更多信息,请参见 set_multicast_loop_v6。
Sourcepub fn set_multicast_loop_v6(&self, on: bool) -> Result<()>
pub fn set_multicast_loop_v6(&self, on: bool) -> Result<()>
Sourcepub fn set_ttl(&self, ttl: u32) -> Result<()>
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)?;
Sourcepub fn tos_v4(&self) -> Result<u32>
pub fn tos_v4(&self) -> Result<u32>
获取该套接字的 IP_TOS 选项值。
有关此选项的更多信息,请参见 set_tos_v4。
Sourcepub fn set_tos_v4(&self, tos: u32) -> Result<()>
pub fn set_tos_v4(&self, tos: u32) -> Result<()>
为该套接字设置 IP_TOS 选项的值。
此值设置了从该套接字发出的每个数据包中使用的服务类型字段。
§Note
- This may not have any effect on IPv6 sockets.
- On Windows,
IP_TOSis only supported on Windows 8+ or Windows Server 2012+.
Sourcepub fn join_multicast_v4(
&self,
multiaddr: Ipv4Addr,
interface: Ipv4Addr,
) -> Result<()>
pub fn join_multicast_v4( &self, multiaddr: Ipv4Addr, interface: Ipv4Addr, ) -> Result<()>
执行 IP_ADD_MEMBERSHIP 类型的操作。
该函数为该套接字指定一个新的多播组以加入。地址必须是有效的多播地址,interface 是系统应通过其加入多播组的本地接口的地址。如果它等于 INADDR_ANY,则由系统选择合适的接口。
Sourcepub fn join_multicast_v6(
&self,
multiaddr: &Ipv6Addr,
interface: u32,
) -> Result<()>
pub fn join_multicast_v6( &self, multiaddr: &Ipv6Addr, interface: u32, ) -> Result<()>
执行 IPV6_ADD_MEMBERSHIP 类型的操作。
该函数为该套接字指定一个新的多播组以加入。地址必须是有效的多播地址,interface 是要加入/离开的接口的索引(或 0,表示任意接口)。
Sourcepub fn leave_multicast_v4(
&self,
multiaddr: Ipv4Addr,
interface: Ipv4Addr,
) -> Result<()>
pub fn leave_multicast_v4( &self, multiaddr: Ipv4Addr, interface: Ipv4Addr, ) -> Result<()>
执行 IP_DROP_MEMBERSHIP 类型的操作。
有关此选项的更多信息,请参见 join_multicast_v4。
Sourcepub fn leave_multicast_v6(
&self,
multiaddr: &Ipv6Addr,
interface: u32,
) -> Result<()>
pub fn leave_multicast_v6( &self, multiaddr: &Ipv6Addr, interface: u32, ) -> Result<()>
执行 IPV6_DROP_MEMBERSHIP 类型的操作。
有关此选项的更多信息,请参见 join_multicast_v6。
Sourcepub fn take_error(&self) -> Result<Option<Error>>
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.
impl AsRawSocket for UdpSocket
docsrs, or Windows only.Source§fn as_raw_socket(&self) -> RawSocket
fn as_raw_socket(&self) -> RawSocket
Source§impl AsSocket for UdpSocket
Available on docsrs, or Windows only.
impl AsSocket for UdpSocket
docsrs, or Windows only.