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

pub struct UdpSocket(_);
Expand description

UDP 套接字。

通过将 UdpSocket 绑定到一个套接字地址来创建 UdpSocket 之后,数据可以是 发送到 和 从哪里接收 任何其他套接字地址。

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

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

Examples

use std::net::UdpSocket;

fn main() -> std::io::Result<()> {
    {
        let 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 是与此对象引用相同的套接字的引用。 两个句柄都将读取和写入相同的端口,并且在一个套接字上设置的选项将传播到另一个套接字。

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 套接字连接到远程地址,从而允许使用 send 和 recv 系统调用来发送数据,并且还应用过滤器以仅接收来自指定地址的数据。

如果 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 套接字移入或移出非阻塞模式。

这将导致 recv,recv_from,send 和 send_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 a nightly-only experimental API. (io_safety #87074)
This is supported on Unix only.

借用文件描述符。 Read more

This is supported on Unix only.

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

从此对象中提取底层原始套接字。

🔬 This is a nightly-only experimental API. (io_safety #87074)

借用套接字。

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

执行转换。

执行转换。

执行转换。

执行转换。

This is supported on Unix only.

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

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

This is supported on Unix only.

消费这个对象,返回原始的底层文件描述符。 Read more

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

Auto Trait Implementations

Blanket Implementations

获取 self 的 TypeId。 Read more

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

从拥有的值中借用。 Read more

执行转换。

执行转换。

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

执行转换。

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

执行转换。