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