Struct std::net::UdpSocket1.0.0[][src]

pub struct UdpSocket(_);
Expand description

UDP 套接字。

通过将 UdpSocket 绑定到一个套接字地址来创建 UdpSocket 之后,数据可以是 sent toreceived from 任何其他套接字地址。

尽管 UDP 是无连接协议,但是此实现提供了一个接口,用于设置一个地址,在该地址处应发送和接收数据。 使用 connect 设置远程地址后,可以使用 sendrecv 向该地址发送数据和从该地址接收数据。

IETF RFC 768 中的用户数据报协议规范中所述,UDP 是无序,不可靠的协议。有关 TCP 原语,请参考 TcpListenerTcpStream

Examples

use std::net::UdpSocket;

fn main() -> std::io::Result<()> {
    {
        let mut socket = UdpSocket::bind("127.0.0.1:34254")?;

        // 在套接字上接收单个数据报消息。
        // 如果 `buf` 太小而无法容纳该消息,它将被切断。
        let mut buf = [0; 10];
        let (amt, src) = socket.recv_from(&mut buf)?;

        // 将 `buf` 声明为接收数据的切片,并将反向数据发送回原点。
        let buf = &mut buf[..amt];
        buf.reverse();
        socket.send_to(buf, &src)?;
    } // 套接字在这里关闭
    Ok(())
}
Run

Implementations

从给定的地址创建一个 UDP 套接字。

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

如果 addr 产生多个地址,则将使用每个地址尝试 bind,直到一个成功并返回套接字为止。

如果没有一个地址成功创建套接字,则返回上一次尝试返回的错误 (最后一个地址)。

Examples

创建绑定到 127.0.0.1:3400 的 UDP 套接字:

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address");
Run

创建绑定到 127.0.0.1:3400 的 UDP 套接字。 如果套接字无法绑定到该地址,请创建绑定到 127.0.0.1:3401 的 UDP 套接字:

use std::net::{SocketAddr, UdpSocket};

let addrs = [
    SocketAddr::from(([127, 0, 0, 1], 3400)),
    SocketAddr::from(([127, 0, 0, 1], 3401)),
];
let socket = UdpSocket::bind(&addrs[..]).expect("couldn't bind to address");
Run

在套接字上接收单个数据报消息。 成功时,返回读取的字节数和源。

必须使用足够大的有效字节数组 buf 来调用函数,以容纳消息字节。

如果消息太长而无法容纳在提供的缓冲区中,则多余的字节可能会被丢弃。

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
let mut buf = [0; 10];
let (number_of_bytes, src_addr) = socket.recv_from(&mut buf)
                                        .expect("Didn't receive data");
let filled_buf = &mut buf[..number_of_bytes];
Run

在套接字上接收单个数据报消息,而无需将其从队列中删除。 成功时,返回读取的字节数和源。

必须使用足够大的有效字节数组 buf 来调用函数,以容纳消息字节。 如果消息太长而无法容纳在提供的缓冲区中,则多余的字节可能会被丢弃。

连续调用返回相同的数据。 这是通过将 MSG_PEEK 作为标志传递到基础 recvfrom 系统调用来完成的。

不要使用此函数来实现繁忙等待,而应使用 libc::poll 来同步一个或多个套接字上的 IO 事件。

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
let mut buf = [0; 10];
let (number_of_bytes, src_addr) = socket.peek_from(&mut buf)
                                        .expect("Didn't receive data");
let filled_buf = &mut buf[..number_of_bytes];
Run

将套接字上的数据发送到给定的地址。成功时,返回写入的字节数。

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

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

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

有关更多详细信息,请参见 Issue #34202

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.send_to(&[0; 10], "127.0.0.1:4242").expect("couldn't send data");
Run

返回此套接字连接到的远程对等方的套接字地址。

Examples

use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.connect("192.168.0.1:41203").expect("couldn't connect to address");
assert_eq!(socket.peer_addr().unwrap(),
           SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 0, 1), 41203)));
Run

如果未连接套接字,它将返回 NotConnected 错误。

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
assert_eq!(socket.peer_addr().unwrap_err().kind(),
           std::io::ErrorKind::NotConnected);
Run

返回创建此套接字的套接字地址。

Examples

use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
assert_eq!(socket.local_addr().unwrap(),
           SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 34254)));
Run

为基础套接字创建一个新的独立拥有的句柄。

返回的 UdpSocket 是与此 object 引用相同的套接字的引用。 两个句柄都将读取和写入相同的端口,并且在一个套接字上设置的选项将传播到另一个套接字。

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
let socket_clone = socket.try_clone().expect("couldn't clone the socket");
Run

将读取超时设置为指定的超时。

如果指定的值为 None,则 read 调用将无限期阻塞。 如果将零 Duration 传递给此方法,则返回 Err

平台特定的行为

由于设置此选项而导致读取超时时,平台可能会返回不同的错误代码。 例如,Unix 通常返回类型为 WouldBlock 的错误,但是 Windows 可能返回 TimedOut

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.set_read_timeout(None).expect("set_read_timeout call failed");
Run

如果将零 Duration 传递给此方法,则返回 Err:

use std::io;
use std::net::UdpSocket;
use std::time::Duration;

let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
let err = result.unwrap_err();
assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
Run

将写超时设置为指定的超时。

如果指定的值为 None,则 write 调用将无限期阻塞。 如果将零 Duration 传递给此方法,则返回 Err

平台特定的行为

由于设置此选项而导致写超时时,平台可能会返回不同的错误代码。 例如,Unix 通常返回类型为 WouldBlock 的错误,但是 Windows 可能返回 TimedOut

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.set_write_timeout(None).expect("set_write_timeout call failed");
Run

如果将零 Duration 传递给此方法,则返回 Err:

use std::io;
use std::net::UdpSocket;
use std::time::Duration;

let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
let err = result.unwrap_err();
assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
Run

返回此套接字的读取超时。

如果超时为 None,则 read 调用将无限期阻塞。

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.set_read_timeout(None).expect("set_read_timeout call failed");
assert_eq!(socket.read_timeout().unwrap(), None);
Run

返回此套接字的写入超时。

如果超时为 None,则 write 调用将无限期阻塞。

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.set_write_timeout(None).expect("set_write_timeout call failed");
assert_eq!(socket.write_timeout().unwrap(), None);
Run

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

启用后,允许此套接字将数据包发送到广播地址。

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.set_broadcast(false).expect("set_broadcast call failed");
Run

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

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

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.set_broadcast(false).expect("set_broadcast call failed");
assert_eq!(socket.broadcast().unwrap(), false);
Run

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

如果启用,则多播数据包将循环回到本地套接字。 请注意,这可能对 IPv6 套接字没有任何影响。

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.set_multicast_loop_v4(false).expect("set_multicast_loop_v4 call failed");
Run

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

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

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.set_multicast_loop_v4(false).expect("set_multicast_loop_v4 call failed");
assert_eq!(socket.multicast_loop_v4().unwrap(), false);
Run

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

指示此套接字的传出多播数据包的生存时间值。 默认值为 1,这意味着除非明确请求,否则多播数据包不会离开本地网络。

请注意,这可能对 IPv6 套接字没有任何影响。

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.set_multicast_ttl_v4(42).expect("set_multicast_ttl_v4 call failed");
Run

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

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

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.set_multicast_ttl_v4(42).expect("set_multicast_ttl_v4 call failed");
assert_eq!(socket.multicast_ttl_v4().unwrap(), 42);
Run

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

控制此套接字是否看到自己发送的多播数据包。 请注意,这可能对 IPv4 套接字没有任何影响。

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.set_multicast_loop_v6(false).expect("set_multicast_loop_v6 call failed");
Run

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

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

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.set_multicast_loop_v6(false).expect("set_multicast_loop_v6 call failed");
assert_eq!(socket.multicast_loop_v6().unwrap(), false);
Run

设置此套接字上 IP_TTL 选项的值。

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

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.set_ttl(42).expect("set_ttl call failed");
Run

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

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

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.set_ttl(42).expect("set_ttl call failed");
assert_eq!(socket.ttl().unwrap(), 42);
Run

执行 IP_ADD_MEMBERSHIP 类型的操作。

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

执行 IPV6_ADD_MEMBERSHIP 类型的操作。

此函数为此套接字指定一个新的多播组。 该地址必须是有效的多播地址,并且 interface 是接口到 join/leave 的索引 (或 0 表示任何接口)。

执行 IP_DROP_MEMBERSHIP 类型的操作。

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

执行 IPV6_DROP_MEMBERSHIP 类型的操作。

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

获取此套接字上 SO_ERROR 选项的值。

这将检索存储在基础套接字中的错误,从而清除进程中的字段。 这对于检查两次调用之间的错误很有用。

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
match socket.take_error() {
    Ok(Some(error)) => println!("UdpSocket error: {:?}", error),
    Ok(None) => println!("No error"),
    Err(error) => println!("UdpSocket.take_error failed: {:?}", error),
}
Run

将此 UDP 套接字连接到远程地址,从而允许使用 sendrecv 系统调用来发送数据,并且还应用过滤器以仅接收来自指定地址的数据。

如果 addr 产生多个地址,则将使用每个地址尝试 connect,直到基础 OS 函数未返回错误为止。 请注意,通常,成功的 connect 调用不会指定有远程服务器在端口上侦听,而是仅在第一次发送后才检测到此错误。 如果操作系统为每个指定的地址返回错误,则返回从上次连接尝试 (最后一个地址) 返回的错误。

Examples

创建绑定到 127.0.0.1:3400 的 UDP 套接字并将该套接字连接到 127.0.0.1:8080:

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address");
socket.connect("127.0.0.1:8080").expect("connect function failed");
Run

与 TCP 情况不同,将地址数组传递给 UDP 套接字的 connect 函数不是一件有用的事情: 在没有应用程序发送数据的情况下,操作系统将无法确定是否有人在监听远程地址。

将套接字上的数据发送到它所连接的远程地址。

UdpSocket::connect 将此套接字连接到远程地址。 如果未连接套接字,则此方法将失败。

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.connect("127.0.0.1:8080").expect("connect function failed");
socket.send(&[0, 1, 2]).expect("couldn't send message");
Run

从套接字连接到的远程地址在套接字上接收单个数据报消息。 成功时,返回读取的字节数。

必须使用足够大的有效字节数组 buf 来调用函数,以容纳消息字节。

如果消息太长而无法容纳在提供的缓冲区中,则多余的字节可能会被丢弃。

UdpSocket::connect 将此套接字连接到远程地址。 如果未连接套接字,则此方法将失败。

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.connect("127.0.0.1:8080").expect("connect function failed");
let mut buf = [0; 10];
match socket.recv(&mut buf) {
    Ok(received) => println!("received {} bytes {:?}", received, &buf[..received]),
    Err(e) => println!("recv function failed: {:?}", e),
}
Run

从套接字所连接的远程地址接收套接字上的单个数据报,而不会从输入队列中删除消息。 成功时,返回偷看的字节数。

必须使用足够大的有效字节数组 buf 来调用函数,以容纳消息字节。 如果消息太长而无法容纳在提供的缓冲区中,则多余的字节可能会被丢弃。

连续调用返回相同的数据。这是通过将 MSG_PEEK 作为标志传递到基础 recv 系统调用来完成的。

不要使用此函数来实现繁忙等待,而应使用 libc::poll 来同步一个或多个套接字上的 IO 事件。

UdpSocket::connect 将此套接字连接到远程地址。如果未连接套接字,则此方法将失败。

Errors

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

Examples

use std::net::UdpSocket;

let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
socket.connect("127.0.0.1:8080").expect("connect function failed");
let mut buf = [0; 10];
match socket.peek(&mut buf) {
    Ok(received) => println!("received {} bytes", received),
    Err(e) => println!("peek function failed: {:?}", e),
}
Run

将此 UDP 套接字移入或移出非阻塞模式。

这将导致 recvrecv_fromsendsend_to 操作变为非阻塞,即立即从其调用中返回。

如果 IO 操作成功,则返回 Ok,并且不需要进一步的操作。 如果 IO 操作无法完成,需要重试,则返回类型为 io::ErrorKind::WouldBlock 的错误。

在 Unix 平台上,调用此方法相当于调用 fcntl FIONBIO。 在 Windows 上,调用此方法对应于调用 ioctlsocket FIONBIO

Examples

创建绑定到 127.0.0.1:7878 的 UDP 套接字,并以非阻塞模式读取字节:

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

let socket = UdpSocket::bind("127.0.0.1:7878").unwrap();
socket.set_nonblocking(true).unwrap();

let mut buf = [0; 10];
let (num_bytes_read, _) = loop {
    match socket.recv_from(&mut buf) {
        Ok(n) => break n,
        Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
            // 等待网络套接字就绪,通常通过平台特定的 API (例如 epoll 或 IOCP) 实现
            wait_for_fd();
        }
        Err(e) => panic!("encountered IO error: {}", e),
    }
};
println!("bytes: {:?}", &buf[..num_bytes_read]);
Run

Trait Implementations

This is supported on Unix only.

提取原始文件描述符。 Read more

This is supported on WASI only.
🔬 This is a nightly-only experimental API. (wasi_ext #71213)

提取原始文件描述符。 Read more

This is supported on Windows only.

从此 object 中提取基础原始套接字。

使用给定的格式化程序格式化该值。 Read more

This is supported on Unix only.

根据给定的原始文件描述符构造 Self 的新实例。 Read more

This is supported on WASI only.
🔬 This is a nightly-only experimental API. (wasi_ext #71213)

根据给定的原始文件描述符构造 Self 的新实例。 Read more

This is supported on Windows only.

从给定的原始套接字创建一个新的 I/O object。 Read more

This is supported on Unix only.

使用此 object,返回原始基础文件描述符。 Read more

This is supported on WASI only.
🔬 This is a nightly-only experimental API. (wasi_ext #71213)

使用此 object,返回原始基础文件描述符。 Read more

This is supported on Windows only.

消耗此对象,返回原始基础套接字。 Read more

Auto Trait Implementations

Blanket Implementations

获取 selfTypeIdRead more

从拥有的值中一成不变地借用。 Read more

从拥有的值中借用。 Read more

执行转换。

执行转换。

发生转换错误时返回的类型。

执行转换。

发生转换错误时返回的类型。

执行转换。