Struct std::net::UdpSocket 1.0.0[−][src]
pub struct UdpSocket(_);
Expand description
UDP 套接字。
通过将 UdpSocket
绑定到一个套接字地址来创建 UdpSocket
之后,数据可以是 sent to 和 received from 任何其他套接字地址。
尽管 UDP 是无连接协议,但是此实现提供了一个接口,用于设置一个地址,在该地址处应发送和接收数据。
使用 connect
设置远程地址后,可以使用 send
和 recv
向该地址发送数据和从该地址接收数据。
如 IETF RFC 768 中的用户数据报协议规范中所述,UDP 是无序,不可靠的协议。有关 TCP 原语,请参考 TcpListener
和 TcpStream
。
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
将读取超时设置为指定的超时。
如果指定的值为 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
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
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
获取此套接字的 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
选项的值。
有关此选项的更多信息,请参见 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
选项的值。
有关此选项的更多信息,请参见 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
选项的值。
有关此选项的更多信息,请参见 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
从此 object 中提取基础原始套接字。