Skip to main content

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