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}