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