std/net/udp.rs
1#[cfg(all(
2 test,
3 not(any(
4 target_os = "emscripten",
5 all(target_os = "wasi", target_env = "p1"),
6 target_env = "sgx",
7 target_os = "xous"
8 ))
9))]
10mod tests;
11
12use crate::fmt;
13use crate::io::{self, ErrorKind};
14use crate::net::{Ipv4Addr, Ipv6Addr, SocketAddr, ToSocketAddrs};
15use crate::sys::net as net_imp;
16use crate::sys_common::{AsInner, FromInner, IntoInner};
17use crate::time::Duration;
18
19/// A UDP socket.
20///
21/// After creating a `UdpSocket` by [`bind`]ing it to a socket address, data can be
22/// [sent to] and [received from] any other socket address.
23///
24/// Although UDP is a connectionless protocol, this implementation provides an interface
25/// to set an address where data should be sent and received from. After setting a remote
26/// address with [`connect`], data can be sent to and received from that address with
27/// [`send`] and [`recv`].
28///
29/// As stated in the User Datagram Protocol's specification in [IETF RFC 768], UDP is
30/// an unordered, unreliable protocol; refer to [`TcpListener`] and [`TcpStream`] for TCP
31/// primitives.
32///
33/// [`bind`]: UdpSocket::bind
34/// [`connect`]: UdpSocket::connect
35/// [IETF RFC 768]: https://tools.ietf.org/html/rfc768
36/// [`recv`]: UdpSocket::recv
37/// [received from]: UdpSocket::recv_from
38/// [`send`]: UdpSocket::send
39/// [sent to]: UdpSocket::send_to
40/// [`TcpListener`]: crate::net::TcpListener
41/// [`TcpStream`]: crate::net::TcpStream
42///
43/// # Examples
44///
45/// ```no_run
46/// use std::net::UdpSocket;
47///
48/// fn main() -> std::io::Result<()> {
49/// {
50/// let socket = UdpSocket::bind("127.0.0.1:34254")?;
51///
52/// // Receives a single datagram message on the socket. If `buf` is too small to hold
53/// // the message, it will be cut off.
54/// let mut buf = [0; 10];
55/// let (amt, src) = socket.recv_from(&mut buf)?;
56///
57/// // Redeclare `buf` as slice of the received data and send reverse data back to origin.
58/// let buf = &mut buf[..amt];
59/// buf.reverse();
60/// socket.send_to(buf, &src)?;
61/// } // the socket is closed here
62/// Ok(())
63/// }
64/// ```
65#[stable(feature = "rust1", since = "1.0.0")]
66pub struct UdpSocket(net_imp::UdpSocket);
67
68impl UdpSocket {
69 /// Creates a UDP socket from the given address.
70 ///
71 /// The address type can be any implementor of [`ToSocketAddrs`] trait. See
72 /// its documentation for concrete examples.
73 ///
74 /// If `addr` yields multiple addresses, `bind` will be attempted with
75 /// each of the addresses until one succeeds and returns the socket. If none
76 /// of the addresses succeed in creating a socket, the error returned from
77 /// the last attempt (the last address) is returned.
78 ///
79 /// # Examples
80 ///
81 /// Creates a UDP socket bound to `127.0.0.1:3400`:
82 ///
83 /// ```no_run
84 /// use std::net::UdpSocket;
85 ///
86 /// let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address");
87 /// ```
88 ///
89 /// Creates a UDP socket bound to `127.0.0.1:3400`. If the socket cannot be
90 /// bound to that address, create a UDP socket bound to `127.0.0.1:3401`:
91 ///
92 /// ```no_run
93 /// use std::net::{SocketAddr, UdpSocket};
94 ///
95 /// let addrs = [
96 /// SocketAddr::from(([127, 0, 0, 1], 3400)),
97 /// SocketAddr::from(([127, 0, 0, 1], 3401)),
98 /// ];
99 /// let socket = UdpSocket::bind(&addrs[..]).expect("couldn't bind to address");
100 /// ```
101 ///
102 /// Creates a UDP socket bound to a port assigned by the operating system
103 /// at `127.0.0.1`.
104 ///
105 /// ```no_run
106 /// use std::net::UdpSocket;
107 ///
108 /// let socket = UdpSocket::bind("127.0.0.1:0").unwrap();
109 /// ```
110 ///
111 /// Note that `bind` declares the scope of your network connection.
112 /// You can only receive datagrams from and send datagrams to
113 /// participants in that view of the network.
114 /// For instance, binding to a loopback address as in the example
115 /// above will prevent you from sending datagrams to another device
116 /// in your local network.
117 ///
118 /// In order to limit your view of the network the least, `bind` to
119 /// [`Ipv4Addr::UNSPECIFIED`] or [`Ipv6Addr::UNSPECIFIED`].
120 #[stable(feature = "rust1", since = "1.0.0")]
121 pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
122 super::each_addr(addr, net_imp::UdpSocket::bind).map(UdpSocket)
123 }
124
125 /// Receives a single datagram message on the socket. On success, returns the number
126 /// of bytes read and the origin.
127 ///
128 /// The function must be called with valid byte array `buf` of sufficient size to
129 /// hold the message bytes. If a message is too long to fit in the supplied buffer,
130 /// excess bytes may be discarded.
131 ///
132 /// # Examples
133 ///
134 /// ```no_run
135 /// use std::net::UdpSocket;
136 ///
137 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
138 /// let mut buf = [0; 10];
139 /// let (number_of_bytes, src_addr) = socket.recv_from(&mut buf)
140 /// .expect("Didn't receive data");
141 /// let filled_buf = &mut buf[..number_of_bytes];
142 /// ```
143 #[stable(feature = "rust1", since = "1.0.0")]
144 pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
145 self.0.recv_from(buf)
146 }
147
148 /// Receives a single datagram message on the socket, without removing it from the
149 /// queue. On success, returns the number of bytes read and the origin.
150 ///
151 /// The function must be called with valid byte array `buf` of sufficient size to
152 /// hold the message bytes. If a message is too long to fit in the supplied buffer,
153 /// excess bytes may be discarded.
154 ///
155 /// Successive calls return the same data. This is accomplished by passing
156 /// `MSG_PEEK` as a flag to the underlying `recvfrom` system call.
157 ///
158 /// Do not use this function to implement busy waiting, instead use `libc::poll` to
159 /// synchronize IO events on one or more sockets.
160 ///
161 /// # Examples
162 ///
163 /// ```no_run
164 /// use std::net::UdpSocket;
165 ///
166 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
167 /// let mut buf = [0; 10];
168 /// let (number_of_bytes, src_addr) = socket.peek_from(&mut buf)
169 /// .expect("Didn't receive data");
170 /// let filled_buf = &mut buf[..number_of_bytes];
171 /// ```
172 #[stable(feature = "peek", since = "1.18.0")]
173 pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
174 self.0.peek_from(buf)
175 }
176
177 /// Sends data on the socket to the given address. On success, returns the
178 /// number of bytes written. Note that the operating system may refuse
179 /// buffers larger than 65507. However, partial writes are not possible
180 /// until buffer sizes above `i32::MAX`.
181 ///
182 /// Address type can be any implementor of [`ToSocketAddrs`] trait. See its
183 /// documentation for concrete examples.
184 ///
185 /// It is possible for `addr` to yield multiple addresses, but `send_to`
186 /// will only send data to the first address yielded by `addr`.
187 ///
188 /// This will return an error when the IP version of the local socket
189 /// does not match that returned from [`ToSocketAddrs`].
190 ///
191 /// See [Issue #34202] for more details.
192 ///
193 /// # Examples
194 ///
195 /// ```no_run
196 /// use std::net::UdpSocket;
197 ///
198 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
199 /// socket.send_to(&[0; 10], "127.0.0.1:4242").expect("couldn't send data");
200 /// ```
201 ///
202 /// [Issue #34202]: https://github.com/rust-lang/rust/issues/34202
203 #[stable(feature = "rust1", since = "1.0.0")]
204 pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A) -> io::Result<usize> {
205 match addr.to_socket_addrs()?.next() {
206 Some(addr) => self.0.send_to(buf, &addr),
207 None => Err(io::const_error!(ErrorKind::InvalidInput, "no addresses to send data to")),
208 }
209 }
210
211 /// Returns the socket address of the remote peer this socket was connected to.
212 ///
213 /// # Examples
214 ///
215 /// ```no_run
216 /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};
217 ///
218 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
219 /// socket.connect("192.168.0.1:41203").expect("couldn't connect to address");
220 /// assert_eq!(socket.peer_addr().unwrap(),
221 /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 0, 1), 41203)));
222 /// ```
223 ///
224 /// If the socket isn't connected, it will return a [`NotConnected`] error.
225 ///
226 /// [`NotConnected`]: io::ErrorKind::NotConnected
227 ///
228 /// ```no_run
229 /// use std::net::UdpSocket;
230 ///
231 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
232 /// assert_eq!(socket.peer_addr().unwrap_err().kind(),
233 /// std::io::ErrorKind::NotConnected);
234 /// ```
235 #[stable(feature = "udp_peer_addr", since = "1.40.0")]
236 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
237 self.0.peer_addr()
238 }
239
240 /// Returns the socket address that this socket was created from.
241 ///
242 /// # Examples
243 ///
244 /// ```no_run
245 /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4, UdpSocket};
246 ///
247 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
248 /// assert_eq!(socket.local_addr().unwrap(),
249 /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 34254)));
250 /// ```
251 #[stable(feature = "rust1", since = "1.0.0")]
252 pub fn local_addr(&self) -> io::Result<SocketAddr> {
253 self.0.socket_addr()
254 }
255
256 /// Creates a new independently owned handle to the underlying socket.
257 ///
258 /// The returned `UdpSocket` is a reference to the same socket that this
259 /// object references. Both handles will read and write the same port, and
260 /// options set on one socket will be propagated to the other.
261 ///
262 /// # Examples
263 ///
264 /// ```no_run
265 /// use std::net::UdpSocket;
266 ///
267 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
268 /// let socket_clone = socket.try_clone().expect("couldn't clone the socket");
269 /// ```
270 #[stable(feature = "rust1", since = "1.0.0")]
271 pub fn try_clone(&self) -> io::Result<UdpSocket> {
272 self.0.duplicate().map(UdpSocket)
273 }
274
275 /// Sets the read timeout to the timeout specified.
276 ///
277 /// If the value specified is [`None`], then [`read`] calls will block
278 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
279 /// passed to this method.
280 ///
281 /// # Platform-specific behavior
282 ///
283 /// Platforms may return a different error code whenever a read times out as
284 /// a result of setting this option. For example Unix typically returns an
285 /// error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
286 ///
287 /// [`read`]: io::Read::read
288 /// [`WouldBlock`]: io::ErrorKind::WouldBlock
289 /// [`TimedOut`]: io::ErrorKind::TimedOut
290 ///
291 /// # Examples
292 ///
293 /// ```no_run
294 /// use std::net::UdpSocket;
295 ///
296 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
297 /// socket.set_read_timeout(None).expect("set_read_timeout call failed");
298 /// ```
299 ///
300 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
301 /// method:
302 ///
303 /// ```no_run
304 /// use std::io;
305 /// use std::net::UdpSocket;
306 /// use std::time::Duration;
307 ///
308 /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
309 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
310 /// let err = result.unwrap_err();
311 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
312 /// ```
313 #[stable(feature = "socket_timeout", since = "1.4.0")]
314 pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
315 self.0.set_read_timeout(dur)
316 }
317
318 /// Sets the write timeout to the timeout specified.
319 ///
320 /// If the value specified is [`None`], then [`write`] calls will block
321 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
322 /// passed to this method.
323 ///
324 /// # Platform-specific behavior
325 ///
326 /// Platforms may return a different error code whenever a write times out
327 /// as a result of setting this option. For example Unix typically returns
328 /// an error of the kind [`WouldBlock`], but Windows may return [`TimedOut`].
329 ///
330 /// [`write`]: io::Write::write
331 /// [`WouldBlock`]: io::ErrorKind::WouldBlock
332 /// [`TimedOut`]: io::ErrorKind::TimedOut
333 ///
334 /// # Examples
335 ///
336 /// ```no_run
337 /// use std::net::UdpSocket;
338 ///
339 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
340 /// socket.set_write_timeout(None).expect("set_write_timeout call failed");
341 /// ```
342 ///
343 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
344 /// method:
345 ///
346 /// ```no_run
347 /// use std::io;
348 /// use std::net::UdpSocket;
349 /// use std::time::Duration;
350 ///
351 /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
352 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
353 /// let err = result.unwrap_err();
354 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
355 /// ```
356 #[stable(feature = "socket_timeout", since = "1.4.0")]
357 pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
358 self.0.set_write_timeout(dur)
359 }
360
361 /// Returns the read timeout of this socket.
362 ///
363 /// If the timeout is [`None`], then [`read`] calls will block indefinitely.
364 ///
365 /// [`read`]: io::Read::read
366 ///
367 /// # Examples
368 ///
369 /// ```no_run
370 /// use std::net::UdpSocket;
371 ///
372 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
373 /// socket.set_read_timeout(None).expect("set_read_timeout call failed");
374 /// assert_eq!(socket.read_timeout().unwrap(), None);
375 /// ```
376 #[stable(feature = "socket_timeout", since = "1.4.0")]
377 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
378 self.0.read_timeout()
379 }
380
381 /// Returns the write timeout of this socket.
382 ///
383 /// If the timeout is [`None`], then [`write`] calls will block indefinitely.
384 ///
385 /// [`write`]: io::Write::write
386 ///
387 /// # Examples
388 ///
389 /// ```no_run
390 /// use std::net::UdpSocket;
391 ///
392 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
393 /// socket.set_write_timeout(None).expect("set_write_timeout call failed");
394 /// assert_eq!(socket.write_timeout().unwrap(), None);
395 /// ```
396 #[stable(feature = "socket_timeout", since = "1.4.0")]
397 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
398 self.0.write_timeout()
399 }
400
401 /// Sets the value of the `SO_BROADCAST` option for this socket.
402 ///
403 /// When enabled, this socket is allowed to send packets to a broadcast
404 /// address.
405 ///
406 /// # Examples
407 ///
408 /// ```no_run
409 /// use std::net::UdpSocket;
410 ///
411 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
412 /// socket.set_broadcast(false).expect("set_broadcast call failed");
413 /// ```
414 #[stable(feature = "net2_mutators", since = "1.9.0")]
415 pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
416 self.0.set_broadcast(broadcast)
417 }
418
419 /// Gets the value of the `SO_BROADCAST` option for this socket.
420 ///
421 /// For more information about this option, see [`UdpSocket::set_broadcast`].
422 ///
423 /// # Examples
424 ///
425 /// ```no_run
426 /// use std::net::UdpSocket;
427 ///
428 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
429 /// socket.set_broadcast(false).expect("set_broadcast call failed");
430 /// assert_eq!(socket.broadcast().unwrap(), false);
431 /// ```
432 #[stable(feature = "net2_mutators", since = "1.9.0")]
433 pub fn broadcast(&self) -> io::Result<bool> {
434 self.0.broadcast()
435 }
436
437 /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
438 ///
439 /// If enabled, multicast packets will be looped back to the local socket.
440 /// Note that this might not have any effect on IPv6 sockets.
441 ///
442 /// # Examples
443 ///
444 /// ```no_run
445 /// use std::net::UdpSocket;
446 ///
447 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
448 /// socket.set_multicast_loop_v4(false).expect("set_multicast_loop_v4 call failed");
449 /// ```
450 #[stable(feature = "net2_mutators", since = "1.9.0")]
451 pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
452 self.0.set_multicast_loop_v4(multicast_loop_v4)
453 }
454
455 /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
456 ///
457 /// For more information about this option, see [`UdpSocket::set_multicast_loop_v4`].
458 ///
459 /// # Examples
460 ///
461 /// ```no_run
462 /// use std::net::UdpSocket;
463 ///
464 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
465 /// socket.set_multicast_loop_v4(false).expect("set_multicast_loop_v4 call failed");
466 /// assert_eq!(socket.multicast_loop_v4().unwrap(), false);
467 /// ```
468 #[stable(feature = "net2_mutators", since = "1.9.0")]
469 pub fn multicast_loop_v4(&self) -> io::Result<bool> {
470 self.0.multicast_loop_v4()
471 }
472
473 /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
474 ///
475 /// Indicates the time-to-live value of outgoing multicast packets for
476 /// this socket. The default value is 1 which means that multicast packets
477 /// don't leave the local network unless explicitly requested.
478 ///
479 /// Note that this might not have any effect on IPv6 sockets.
480 ///
481 /// # Examples
482 ///
483 /// ```no_run
484 /// use std::net::UdpSocket;
485 ///
486 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
487 /// socket.set_multicast_ttl_v4(42).expect("set_multicast_ttl_v4 call failed");
488 /// ```
489 #[stable(feature = "net2_mutators", since = "1.9.0")]
490 pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
491 self.0.set_multicast_ttl_v4(multicast_ttl_v4)
492 }
493
494 /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
495 ///
496 /// For more information about this option, see [`UdpSocket::set_multicast_ttl_v4`].
497 ///
498 /// # Examples
499 ///
500 /// ```no_run
501 /// use std::net::UdpSocket;
502 ///
503 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
504 /// socket.set_multicast_ttl_v4(42).expect("set_multicast_ttl_v4 call failed");
505 /// assert_eq!(socket.multicast_ttl_v4().unwrap(), 42);
506 /// ```
507 #[stable(feature = "net2_mutators", since = "1.9.0")]
508 pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
509 self.0.multicast_ttl_v4()
510 }
511
512 /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
513 ///
514 /// Controls whether this socket sees the multicast packets it sends itself.
515 /// Note that this might not have any affect on IPv4 sockets.
516 ///
517 /// # Examples
518 ///
519 /// ```no_run
520 /// use std::net::UdpSocket;
521 ///
522 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
523 /// socket.set_multicast_loop_v6(false).expect("set_multicast_loop_v6 call failed");
524 /// ```
525 #[stable(feature = "net2_mutators", since = "1.9.0")]
526 pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
527 self.0.set_multicast_loop_v6(multicast_loop_v6)
528 }
529
530 /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
531 ///
532 /// For more information about this option, see [`UdpSocket::set_multicast_loop_v6`].
533 ///
534 /// # Examples
535 ///
536 /// ```no_run
537 /// use std::net::UdpSocket;
538 ///
539 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
540 /// socket.set_multicast_loop_v6(false).expect("set_multicast_loop_v6 call failed");
541 /// assert_eq!(socket.multicast_loop_v6().unwrap(), false);
542 /// ```
543 #[stable(feature = "net2_mutators", since = "1.9.0")]
544 pub fn multicast_loop_v6(&self) -> io::Result<bool> {
545 self.0.multicast_loop_v6()
546 }
547
548 /// Sets the value for the `IP_TTL` option on this socket.
549 ///
550 /// This value sets the time-to-live field that is used in every packet sent
551 /// from this socket.
552 ///
553 /// # Examples
554 ///
555 /// ```no_run
556 /// use std::net::UdpSocket;
557 ///
558 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
559 /// socket.set_ttl(42).expect("set_ttl call failed");
560 /// ```
561 #[stable(feature = "net2_mutators", since = "1.9.0")]
562 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
563 self.0.set_ttl(ttl)
564 }
565
566 /// Gets the value of the `IP_TTL` option for this socket.
567 ///
568 /// For more information about this option, see [`UdpSocket::set_ttl`].
569 ///
570 /// # Examples
571 ///
572 /// ```no_run
573 /// use std::net::UdpSocket;
574 ///
575 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
576 /// socket.set_ttl(42).expect("set_ttl call failed");
577 /// assert_eq!(socket.ttl().unwrap(), 42);
578 /// ```
579 #[stable(feature = "net2_mutators", since = "1.9.0")]
580 pub fn ttl(&self) -> io::Result<u32> {
581 self.0.ttl()
582 }
583
584 /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
585 ///
586 /// This function specifies a new multicast group for this socket to join.
587 /// The address must be a valid multicast address, and `interface` is the
588 /// address of the local interface with which the system should join the
589 /// multicast group. If it's equal to [`UNSPECIFIED`](Ipv4Addr::UNSPECIFIED)
590 /// then an appropriate interface is chosen by the system.
591 #[stable(feature = "net2_mutators", since = "1.9.0")]
592 pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
593 self.0.join_multicast_v4(multiaddr, interface)
594 }
595
596 /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
597 ///
598 /// This function specifies a new multicast group for this socket to join.
599 /// The address must be a valid multicast address, and `interface` is the
600 /// index of the interface to join/leave (or 0 to indicate any interface).
601 #[stable(feature = "net2_mutators", since = "1.9.0")]
602 pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
603 self.0.join_multicast_v6(multiaddr, interface)
604 }
605
606 /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
607 ///
608 /// For more information about this option, see [`UdpSocket::join_multicast_v4`].
609 #[stable(feature = "net2_mutators", since = "1.9.0")]
610 pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
611 self.0.leave_multicast_v4(multiaddr, interface)
612 }
613
614 /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
615 ///
616 /// For more information about this option, see [`UdpSocket::join_multicast_v6`].
617 #[stable(feature = "net2_mutators", since = "1.9.0")]
618 pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
619 self.0.leave_multicast_v6(multiaddr, interface)
620 }
621
622 /// Gets the value of the `SO_ERROR` option on this socket.
623 ///
624 /// This will retrieve the stored error in the underlying socket, clearing
625 /// the field in the process. This can be useful for checking errors between
626 /// calls.
627 ///
628 /// # Examples
629 ///
630 /// ```no_run
631 /// use std::net::UdpSocket;
632 ///
633 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
634 /// match socket.take_error() {
635 /// Ok(Some(error)) => println!("UdpSocket error: {error:?}"),
636 /// Ok(None) => println!("No error"),
637 /// Err(error) => println!("UdpSocket.take_error failed: {error:?}"),
638 /// }
639 /// ```
640 #[stable(feature = "net2_mutators", since = "1.9.0")]
641 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
642 self.0.take_error()
643 }
644
645 /// Connects this UDP socket to a remote address, allowing the `send` and
646 /// `recv` syscalls to be used to send data and also applies filters to only
647 /// receive data from the specified address.
648 ///
649 /// If `addr` yields multiple addresses, `connect` will be attempted with
650 /// each of the addresses until the underlying OS function returns no
651 /// error. Note that usually, a successful `connect` call does not specify
652 /// that there is a remote server listening on the port, rather, such an
653 /// error would only be detected after the first send. If the OS returns an
654 /// error for each of the specified addresses, the error returned from the
655 /// last connection attempt (the last address) is returned.
656 ///
657 /// # Examples
658 ///
659 /// Creates a UDP socket bound to `127.0.0.1:3400` and connect the socket to
660 /// `127.0.0.1:8080`:
661 ///
662 /// ```no_run
663 /// use std::net::UdpSocket;
664 ///
665 /// let socket = UdpSocket::bind("127.0.0.1:3400").expect("couldn't bind to address");
666 /// socket.connect("127.0.0.1:8080").expect("connect function failed");
667 /// ```
668 ///
669 /// Unlike in the TCP case, passing an array of addresses to the `connect`
670 /// function of a UDP socket is not a useful thing to do: The OS will be
671 /// unable to determine whether something is listening on the remote
672 /// address without the application sending data.
673 ///
674 /// If your first `connect` is to a loopback address, subsequent
675 /// `connect`s to non-loopback addresses might fail, depending
676 /// on the platform.
677 #[stable(feature = "net2_mutators", since = "1.9.0")]
678 pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
679 super::each_addr(addr, |addr| self.0.connect(addr))
680 }
681
682 /// Sends data on the socket to the remote address to which it is connected.
683 /// On success, returns the number of bytes written. Note that the operating
684 /// system may refuse buffers larger than 65507. However, partial writes are
685 /// not possible until buffer sizes above `i32::MAX`.
686 ///
687 /// [`UdpSocket::connect`] will connect this socket to a remote address. This
688 /// method will fail if the socket is not connected.
689 ///
690 /// # Examples
691 ///
692 /// ```no_run
693 /// use std::net::UdpSocket;
694 ///
695 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
696 /// socket.connect("127.0.0.1:8080").expect("connect function failed");
697 /// socket.send(&[0, 1, 2]).expect("couldn't send message");
698 /// ```
699 #[stable(feature = "net2_mutators", since = "1.9.0")]
700 pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
701 self.0.send(buf)
702 }
703
704 /// Receives a single datagram message on the socket from the remote address to
705 /// which it is connected. On success, returns the number of bytes read.
706 ///
707 /// The function must be called with valid byte array `buf` of sufficient size to
708 /// hold the message bytes. If a message is too long to fit in the supplied buffer,
709 /// excess bytes may be discarded.
710 ///
711 /// [`UdpSocket::connect`] will connect this socket to a remote address. This
712 /// method will fail if the socket is not connected.
713 ///
714 /// # Examples
715 ///
716 /// ```no_run
717 /// use std::net::UdpSocket;
718 ///
719 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
720 /// socket.connect("127.0.0.1:8080").expect("connect function failed");
721 /// let mut buf = [0; 10];
722 /// match socket.recv(&mut buf) {
723 /// Ok(received) => println!("received {received} bytes {:?}", &buf[..received]),
724 /// Err(e) => println!("recv function failed: {e:?}"),
725 /// }
726 /// ```
727 #[stable(feature = "net2_mutators", since = "1.9.0")]
728 pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
729 self.0.recv(buf)
730 }
731
732 /// Receives single datagram on the socket from the remote address to which it is
733 /// connected, without removing the message from input queue. On success, returns
734 /// the number of bytes peeked.
735 ///
736 /// The function must be called with valid byte array `buf` of sufficient size to
737 /// hold the message bytes. If a message is too long to fit in the supplied buffer,
738 /// excess bytes may be discarded.
739 ///
740 /// Successive calls return the same data. This is accomplished by passing
741 /// `MSG_PEEK` as a flag to the underlying `recv` system call.
742 ///
743 /// Do not use this function to implement busy waiting, instead use `libc::poll` to
744 /// synchronize IO events on one or more sockets.
745 ///
746 /// [`UdpSocket::connect`] will connect this socket to a remote address. This
747 /// method will fail if the socket is not connected.
748 ///
749 /// # Errors
750 ///
751 /// This method will fail if the socket is not connected. The `connect` method
752 /// will connect this socket to a remote address.
753 ///
754 /// # Examples
755 ///
756 /// ```no_run
757 /// use std::net::UdpSocket;
758 ///
759 /// let socket = UdpSocket::bind("127.0.0.1:34254").expect("couldn't bind to address");
760 /// socket.connect("127.0.0.1:8080").expect("connect function failed");
761 /// let mut buf = [0; 10];
762 /// match socket.peek(&mut buf) {
763 /// Ok(received) => println!("received {received} bytes"),
764 /// Err(e) => println!("peek function failed: {e:?}"),
765 /// }
766 /// ```
767 #[stable(feature = "peek", since = "1.18.0")]
768 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
769 self.0.peek(buf)
770 }
771
772 /// Moves this UDP socket into or out of nonblocking mode.
773 ///
774 /// This will result in `recv`, `recv_from`, `send`, and `send_to` system
775 /// operations becoming nonblocking, i.e., immediately returning from their
776 /// calls. If the IO operation is successful, `Ok` is returned and no
777 /// further action is required. If the IO operation could not be completed
778 /// and needs to be retried, an error with kind
779 /// [`io::ErrorKind::WouldBlock`] is returned.
780 ///
781 /// On Unix platforms, calling this method corresponds to calling `fcntl`
782 /// `FIONBIO`. On Windows calling this method corresponds to calling
783 /// `ioctlsocket` `FIONBIO`.
784 ///
785 /// # Examples
786 ///
787 /// Creates a UDP socket bound to `127.0.0.1:7878` and read bytes in
788 /// nonblocking mode:
789 ///
790 /// ```no_run
791 /// use std::io;
792 /// use std::net::UdpSocket;
793 ///
794 /// let socket = UdpSocket::bind("127.0.0.1:7878").unwrap();
795 /// socket.set_nonblocking(true).unwrap();
796 ///
797 /// # fn wait_for_fd() { unimplemented!() }
798 /// let mut buf = [0; 10];
799 /// let (num_bytes_read, _) = loop {
800 /// match socket.recv_from(&mut buf) {
801 /// Ok(n) => break n,
802 /// Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
803 /// // wait until network socket is ready, typically implemented
804 /// // via platform-specific APIs such as epoll or IOCP
805 /// wait_for_fd();
806 /// }
807 /// Err(e) => panic!("encountered IO error: {e}"),
808 /// }
809 /// };
810 /// println!("bytes: {:?}", &buf[..num_bytes_read]);
811 /// ```
812 #[stable(feature = "net2_mutators", since = "1.9.0")]
813 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
814 self.0.set_nonblocking(nonblocking)
815 }
816}
817
818// In addition to the `impl`s here, `UdpSocket` also has `impl`s for
819// `AsFd`/`From<OwnedFd>`/`Into<OwnedFd>` and
820// `AsRawFd`/`IntoRawFd`/`FromRawFd`, on Unix and WASI, and
821// `AsSocket`/`From<OwnedSocket>`/`Into<OwnedSocket>` and
822// `AsRawSocket`/`IntoRawSocket`/`FromRawSocket` on Windows.
823
824impl AsInner<net_imp::UdpSocket> for UdpSocket {
825 #[inline]
826 fn as_inner(&self) -> &net_imp::UdpSocket {
827 &self.0
828 }
829}
830
831impl FromInner<net_imp::UdpSocket> for UdpSocket {
832 fn from_inner(inner: net_imp::UdpSocket) -> UdpSocket {
833 UdpSocket(inner)
834 }
835}
836
837impl IntoInner<net_imp::UdpSocket> for UdpSocket {
838 fn into_inner(self) -> net_imp::UdpSocket {
839 self.0
840 }
841}
842
843#[stable(feature = "rust1", since = "1.0.0")]
844impl fmt::Debug for UdpSocket {
845 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
846 self.0.fmt(f)
847 }
848}