1//! Primitives for working with UDP.
2//!
3//! The types provided in this module are non-blocking by default and are
4//! designed to be portable across all supported Mio platforms. As long as the
5//! [portability guidelines] are followed, the behavior should be identical no
6//! matter the target platform.
7//!
8//! [portability guidelines]: ../struct.Poll.html#portability
9
10use crate::io_source::IoSource;
11use crate::{event, sys, Interest, Registry, Token};
12
13use std::fmt;
14use std::io;
15use std::net;
16use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
17#[cfg(unix)]
18use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
19#[cfg(windows)]
20use std::os::windows::io::{AsRawSocket, FromRawSocket, IntoRawSocket, RawSocket};
21
22/// A User Datagram Protocol socket.
23///
24/// This is an implementation of a bound UDP socket. This supports both IPv4 and
25/// IPv6 addresses, and there is no corresponding notion of a server because UDP
26/// is a datagram protocol.
27///
28/// # Examples
29///
30#[cfg_attr(feature = "os-poll", doc = "```")]
31#[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
32/// # use std::error::Error;
33/// #
34/// # fn main() -> Result<(), Box<dyn Error>> {
35/// // An Echo program:
36/// // SENDER -> sends a message.
37/// // ECHOER -> listens and prints the message received.
38///
39/// use mio::net::UdpSocket;
40/// use mio::{Events, Interest, Poll, Token};
41/// use std::time::Duration;
42///
43/// const SENDER: Token = Token(0);
44/// const ECHOER: Token = Token(1);
45///
46/// // This operation will fail if the address is in use, so we select different ports for each
47/// // socket.
48/// let mut sender_socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
49/// let mut echoer_socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
50///
51/// // If we do not use connect here, SENDER and ECHOER would need to call send_to and recv_from
52/// // respectively.
53/// sender_socket.connect(echoer_socket.local_addr()?)?;
54///
55/// // We need a Poll to check if SENDER is ready to be written into, and if ECHOER is ready to be
56/// // read from.
57/// let mut poll = Poll::new()?;
58///
59/// // We register our sockets here so that we can check if they are ready to be written/read.
60/// poll.registry().register(&mut sender_socket, SENDER, Interest::WRITABLE)?;
61/// poll.registry().register(&mut echoer_socket, ECHOER, Interest::READABLE)?;
62///
63/// let msg_to_send = [9; 9];
64/// let mut buffer = [0; 9];
65///
66/// let mut events = Events::with_capacity(128);
67/// loop {
68/// poll.poll(&mut events, Some(Duration::from_millis(100)))?;
69/// for event in events.iter() {
70/// match event.token() {
71/// // Our SENDER is ready to be written into.
72/// SENDER => {
73/// let bytes_sent = sender_socket.send(&msg_to_send)?;
74/// assert_eq!(bytes_sent, 9);
75/// println!("sent {:?} -> {:?} bytes", msg_to_send, bytes_sent);
76/// },
77/// // Our ECHOER is ready to be read from.
78/// ECHOER => {
79/// let num_recv = echoer_socket.recv(&mut buffer)?;
80/// println!("echo {:?} -> {:?}", buffer, num_recv);
81/// buffer = [0; 9];
82/// # _ = buffer; // Silence unused assignment warning.
83/// # return Ok(());
84/// }
85/// _ => unreachable!()
86/// }
87/// }
88/// }
89/// # }
90/// ```
91pub struct UdpSocket {
92 inner: IoSource<net::UdpSocket>,
93}
94
95impl UdpSocket {
96 /// Creates a UDP socket from the given address.
97 ///
98 /// # Examples
99 ///
100 #[cfg_attr(feature = "os-poll", doc = "```")]
101 #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
102 /// # use std::error::Error;
103 /// #
104 /// # fn main() -> Result<(), Box<dyn Error>> {
105 /// use mio::net::UdpSocket;
106 ///
107 /// // We must bind it to an open address.
108 /// let socket = match UdpSocket::bind("127.0.0.1:0".parse()?) {
109 /// Ok(new_socket) => new_socket,
110 /// Err(fail) => {
111 /// // We panic! here, but you could try to bind it again on another address.
112 /// panic!("Failed to bind socket. {:?}", fail);
113 /// }
114 /// };
115 ///
116 /// // Our socket was created, but we should not use it before checking it's readiness.
117 /// # drop(socket); // Silence unused variable warning.
118 /// # Ok(())
119 /// # }
120 /// ```
121 pub fn bind(addr: SocketAddr) -> io::Result<UdpSocket> {
122 sys::udp::bind(addr).map(UdpSocket::from_std)
123 }
124
125 /// Creates a new `UdpSocket` from a standard `net::UdpSocket`.
126 ///
127 /// This function is intended to be used to wrap a UDP socket from the
128 /// standard library in the Mio equivalent. The conversion assumes nothing
129 /// about the underlying socket; it is left up to the user to set it in
130 /// non-blocking mode.
131 pub fn from_std(socket: net::UdpSocket) -> UdpSocket {
132 UdpSocket {
133 inner: IoSource::new(socket),
134 }
135 }
136
137 /// Returns the socket address that this socket was created from.
138 ///
139 /// # Examples
140 ///
141 // This assertion is almost, but not quite, universal. It fails on
142 // shared-IP FreeBSD jails. It's hard for mio to know whether we're jailed,
143 // so simply disable the test on FreeBSD.
144 #[cfg_attr(all(feature = "os-poll", not(target_os = "freebsd")), doc = "```")]
145 #[cfg_attr(
146 any(not(feature = "os-poll"), target_os = "freebsd"),
147 doc = "```ignore"
148 )]
149 /// # use std::error::Error;
150 /// #
151 /// # fn main() -> Result<(), Box<dyn Error>> {
152 /// use mio::net::UdpSocket;
153 ///
154 /// let addr = "127.0.0.1:0".parse()?;
155 /// let socket = UdpSocket::bind(addr)?;
156 /// assert_eq!(socket.local_addr()?.ip(), addr.ip());
157 /// # Ok(())
158 /// # }
159 /// ```
160 pub fn local_addr(&self) -> io::Result<SocketAddr> {
161 self.inner.local_addr()
162 }
163
164 /// Returns the socket address of the remote peer this socket was connected to.
165 ///
166 /// # Examples
167 ///
168 #[cfg_attr(feature = "os-poll", doc = "```")]
169 #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
170 /// # use std::error::Error;
171 /// #
172 /// # fn main() -> Result<(), Box<dyn Error>> {
173 /// use mio::net::UdpSocket;
174 ///
175 /// let addr = "127.0.0.1:0".parse()?;
176 /// let peer_addr = "127.0.0.1:11100".parse()?;
177 /// let socket = UdpSocket::bind(addr)?;
178 /// socket.connect(peer_addr)?;
179 /// assert_eq!(socket.peer_addr()?.ip(), peer_addr.ip());
180 /// # Ok(())
181 /// # }
182 /// ```
183 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
184 self.inner.peer_addr()
185 }
186
187 /// Sends data on the socket to the given address. On success, returns the
188 /// number of bytes written.
189 ///
190 /// Address type can be any implementor of `ToSocketAddrs` trait. See its
191 /// documentation for concrete examples.
192 ///
193 /// # Examples
194 ///
195 /// ```no_run
196 /// # use std::error::Error;
197 /// # fn main() -> Result<(), Box<dyn Error>> {
198 /// use mio::net::UdpSocket;
199 ///
200 /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
201 ///
202 /// // We must check if the socket is writable before calling send_to,
203 /// // or we could run into a WouldBlock error.
204 ///
205 /// let bytes_sent = socket.send_to(&[9; 9], "127.0.0.1:11100".parse()?)?;
206 /// assert_eq!(bytes_sent, 9);
207 /// #
208 /// # Ok(())
209 /// # }
210 /// ```
211 pub fn send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result<usize> {
212 self.inner.do_io(|inner| inner.send_to(buf, target))
213 }
214
215 /// Receives data from the socket. On success, returns the number of bytes
216 /// read and the address from whence the data came.
217 ///
218 /// # Notes
219 ///
220 /// On Windows, if the data is larger than the buffer specified, the buffer
221 /// is filled with the first part of the data, and recv_from returns the error
222 /// WSAEMSGSIZE(10040). The excess data is lost.
223 /// Make sure to always use a sufficiently large buffer to hold the
224 /// maximum UDP packet size, which can be up to 65536 bytes in size.
225 ///
226 /// # Examples
227 ///
228 /// ```no_run
229 /// # use std::error::Error;
230 /// #
231 /// # fn main() -> Result<(), Box<dyn Error>> {
232 /// use mio::net::UdpSocket;
233 ///
234 /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
235 ///
236 /// // We must check if the socket is readable before calling recv_from,
237 /// // or we could run into a WouldBlock error.
238 ///
239 /// let mut buf = [0; 9];
240 /// let (num_recv, from_addr) = socket.recv_from(&mut buf)?;
241 /// println!("Received {:?} -> {:?} bytes from {:?}", buf, num_recv, from_addr);
242 /// #
243 /// # Ok(())
244 /// # }
245 /// ```
246 pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
247 self.inner.do_io(|inner| inner.recv_from(buf))
248 }
249
250 /// Receives data from the socket, without removing it from the input queue.
251 /// On success, returns the number of bytes read and the address from whence
252 /// the data came.
253 ///
254 /// # Notes
255 ///
256 /// On Windows, if the data is larger than the buffer specified, the buffer
257 /// is filled with the first part of the data, and peek_from returns the error
258 /// WSAEMSGSIZE(10040). The excess data is lost.
259 /// Make sure to always use a sufficiently large buffer to hold the
260 /// maximum UDP packet size, which can be up to 65536 bytes in size.
261 ///
262 /// # Examples
263 ///
264 /// ```no_run
265 /// # use std::error::Error;
266 /// #
267 /// # fn main() -> Result<(), Box<dyn Error>> {
268 /// use mio::net::UdpSocket;
269 ///
270 /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
271 ///
272 /// // We must check if the socket is readable before calling recv_from,
273 /// // or we could run into a WouldBlock error.
274 ///
275 /// let mut buf = [0; 9];
276 /// let (num_recv, from_addr) = socket.peek_from(&mut buf)?;
277 /// println!("Received {:?} -> {:?} bytes from {:?}", buf, num_recv, from_addr);
278 /// #
279 /// # Ok(())
280 /// # }
281 /// ```
282 pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
283 self.inner.do_io(|inner| inner.peek_from(buf))
284 }
285
286 /// Sends data on the socket to the address previously bound via connect(). On success,
287 /// returns the number of bytes written.
288 pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
289 self.inner.do_io(|inner| inner.send(buf))
290 }
291
292 /// Receives data from the socket previously bound with connect(). On success, returns
293 /// the number of bytes read.
294 ///
295 /// # Notes
296 ///
297 /// On Windows, if the data is larger than the buffer specified, the buffer
298 /// is filled with the first part of the data, and recv returns the error
299 /// WSAEMSGSIZE(10040). The excess data is lost.
300 /// Make sure to always use a sufficiently large buffer to hold the
301 /// maximum UDP packet size, which can be up to 65536 bytes in size.
302 pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
303 self.inner.do_io(|inner| inner.recv(buf))
304 }
305
306 /// Receives data from the socket, without removing it from the input queue.
307 /// On success, returns the number of bytes read.
308 ///
309 /// # Notes
310 ///
311 /// On Windows, if the data is larger than the buffer specified, the buffer
312 /// is filled with the first part of the data, and peek returns the error
313 /// WSAEMSGSIZE(10040). The excess data is lost.
314 /// Make sure to always use a sufficiently large buffer to hold the
315 /// maximum UDP packet size, which can be up to 65536 bytes in size.
316 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
317 self.inner.do_io(|inner| inner.peek(buf))
318 }
319
320 /// Connects the UDP socket setting the default destination for `send()`
321 /// and limiting packets that are read via `recv` from the address specified
322 /// in `addr`.
323 ///
324 /// This may return a `WouldBlock` in which case the socket connection
325 /// cannot be completed immediately, it usually means there are insufficient
326 /// entries in the routing cache.
327 pub fn connect(&self, addr: SocketAddr) -> io::Result<()> {
328 self.inner.connect(addr)
329 }
330
331 /// Sets the value of the `SO_BROADCAST` option for this socket.
332 ///
333 /// When enabled, this socket is allowed to send packets to a broadcast
334 /// address.
335 ///
336 /// # Examples
337 ///
338 #[cfg_attr(feature = "os-poll", doc = "```")]
339 #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
340 /// # use std::error::Error;
341 /// #
342 /// # fn main() -> Result<(), Box<dyn Error>> {
343 /// use mio::net::UdpSocket;
344 ///
345 /// let broadcast_socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
346 /// if broadcast_socket.broadcast()? == false {
347 /// broadcast_socket.set_broadcast(true)?;
348 /// }
349 ///
350 /// assert_eq!(broadcast_socket.broadcast()?, true);
351 /// #
352 /// # Ok(())
353 /// # }
354 /// ```
355 pub fn set_broadcast(&self, on: bool) -> io::Result<()> {
356 self.inner.set_broadcast(on)
357 }
358
359 /// Gets the value of the `SO_BROADCAST` option for this socket.
360 ///
361 /// For more information about this option, see
362 /// [`set_broadcast`][link].
363 ///
364 /// [link]: #method.set_broadcast
365 ///
366 /// # Examples
367 ///
368 #[cfg_attr(feature = "os-poll", doc = "```")]
369 #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
370 /// # use std::error::Error;
371 /// #
372 /// # fn main() -> Result<(), Box<dyn Error>> {
373 /// use mio::net::UdpSocket;
374 ///
375 /// let broadcast_socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
376 /// assert_eq!(broadcast_socket.broadcast()?, false);
377 /// #
378 /// # Ok(())
379 /// # }
380 /// ```
381 pub fn broadcast(&self) -> io::Result<bool> {
382 self.inner.broadcast()
383 }
384
385 /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
386 ///
387 /// If enabled, multicast packets will be looped back to the local socket.
388 /// Note that this may not have any affect on IPv6 sockets.
389 pub fn set_multicast_loop_v4(&self, on: bool) -> io::Result<()> {
390 self.inner.set_multicast_loop_v4(on)
391 }
392
393 /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
394 ///
395 /// For more information about this option, see
396 /// [`set_multicast_loop_v4`][link].
397 ///
398 /// [link]: #method.set_multicast_loop_v4
399 pub fn multicast_loop_v4(&self) -> io::Result<bool> {
400 self.inner.multicast_loop_v4()
401 }
402
403 /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
404 ///
405 /// Indicates the time-to-live value of outgoing multicast packets for
406 /// this socket. The default value is 1 which means that multicast packets
407 /// don't leave the local network unless explicitly requested.
408 ///
409 /// Note that this may not have any affect on IPv6 sockets.
410 pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> {
411 self.inner.set_multicast_ttl_v4(ttl)
412 }
413
414 /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
415 ///
416 /// For more information about this option, see
417 /// [`set_multicast_ttl_v4`][link].
418 ///
419 /// [link]: #method.set_multicast_ttl_v4
420 pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
421 self.inner.multicast_ttl_v4()
422 }
423
424 /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
425 ///
426 /// Controls whether this socket sees the multicast packets it sends itself.
427 /// Note that this may not have any affect on IPv4 sockets.
428 pub fn set_multicast_loop_v6(&self, on: bool) -> io::Result<()> {
429 self.inner.set_multicast_loop_v6(on)
430 }
431
432 /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
433 ///
434 /// For more information about this option, see
435 /// [`set_multicast_loop_v6`][link].
436 ///
437 /// [link]: #method.set_multicast_loop_v6
438 pub fn multicast_loop_v6(&self) -> io::Result<bool> {
439 self.inner.multicast_loop_v6()
440 }
441
442 /// Sets the value for the `IP_TTL` option on this socket.
443 ///
444 /// This value sets the time-to-live field that is used in every packet sent
445 /// from this socket.
446 ///
447 /// # Examples
448 ///
449 #[cfg_attr(feature = "os-poll", doc = "```")]
450 #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
451 /// # use std::error::Error;
452 /// #
453 /// # fn main() -> Result<(), Box<dyn Error>> {
454 /// use mio::net::UdpSocket;
455 ///
456 /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
457 /// if socket.ttl()? < 255 {
458 /// socket.set_ttl(255)?;
459 /// }
460 ///
461 /// assert_eq!(socket.ttl()?, 255);
462 /// #
463 /// # Ok(())
464 /// # }
465 /// ```
466 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
467 self.inner.set_ttl(ttl)
468 }
469
470 /// Gets the value of the `IP_TTL` option for this socket.
471 ///
472 /// For more information about this option, see [`set_ttl`][link].
473 ///
474 /// [link]: #method.set_ttl
475 ///
476 /// # Examples
477 ///
478 #[cfg_attr(feature = "os-poll", doc = "```")]
479 #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")]
480 /// # use std::error::Error;
481 /// #
482 /// # fn main() -> Result<(), Box<dyn Error>> {
483 /// use mio::net::UdpSocket;
484 ///
485 /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?;
486 /// socket.set_ttl(255)?;
487 ///
488 /// assert_eq!(socket.ttl()?, 255);
489 /// #
490 /// # Ok(())
491 /// # }
492 /// ```
493 pub fn ttl(&self) -> io::Result<u32> {
494 self.inner.ttl()
495 }
496
497 /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
498 ///
499 /// This function specifies a new multicast group for this socket to join.
500 /// The address must be a valid multicast address, and `interface` is the
501 /// address of the local interface with which the system should join the
502 /// multicast group. If it's equal to `INADDR_ANY` then an appropriate
503 /// interface is chosen by the system.
504 #[allow(clippy::trivially_copy_pass_by_ref)]
505 pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
506 self.inner.join_multicast_v4(multiaddr, interface)
507 }
508
509 /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
510 ///
511 /// This function specifies a new multicast group for this socket to join.
512 /// The address must be a valid multicast address, and `interface` is the
513 /// index of the interface to join/leave (or 0 to indicate any interface).
514 #[allow(clippy::trivially_copy_pass_by_ref)]
515 pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
516 self.inner.join_multicast_v6(multiaddr, interface)
517 }
518
519 /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
520 ///
521 /// For more information about this option, see
522 /// [`join_multicast_v4`][link].
523 ///
524 /// [link]: #method.join_multicast_v4
525 #[allow(clippy::trivially_copy_pass_by_ref)]
526 pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
527 self.inner.leave_multicast_v4(multiaddr, interface)
528 }
529
530 /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
531 ///
532 /// For more information about this option, see
533 /// [`join_multicast_v6`][link].
534 ///
535 /// [link]: #method.join_multicast_v6
536 #[allow(clippy::trivially_copy_pass_by_ref)]
537 pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
538 self.inner.leave_multicast_v6(multiaddr, interface)
539 }
540
541 /// Get the value of the `IPV6_V6ONLY` option on this socket.
542 #[allow(clippy::trivially_copy_pass_by_ref)]
543 pub fn only_v6(&self) -> io::Result<bool> {
544 sys::udp::only_v6(&self.inner)
545 }
546
547 /// Get the value of the `SO_ERROR` option on this socket.
548 ///
549 /// This will retrieve the stored error in the underlying socket, clearing
550 /// the field in the process. This can be useful for checking errors between
551 /// calls.
552 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
553 self.inner.take_error()
554 }
555
556 /// Execute an I/O operation ensuring that the socket receives more events
557 /// if it hits a [`WouldBlock`] error.
558 ///
559 /// # Notes
560 ///
561 /// This method is required to be called for **all** I/O operations to
562 /// ensure the user will receive events once the socket is ready again after
563 /// returning a [`WouldBlock`] error.
564 ///
565 /// [`WouldBlock`]: io::ErrorKind::WouldBlock
566 ///
567 /// # Examples
568 ///
569 #[cfg_attr(unix, doc = "```no_run")]
570 #[cfg_attr(windows, doc = "```ignore")]
571 /// # use std::error::Error;
572 /// #
573 /// # fn main() -> Result<(), Box<dyn Error>> {
574 /// use std::io;
575 /// #[cfg(unix)]
576 /// use std::os::unix::io::AsRawFd;
577 /// #[cfg(windows)]
578 /// use std::os::windows::io::AsRawSocket;
579 /// use mio::net::UdpSocket;
580 ///
581 /// let address = "127.0.0.1:8080".parse().unwrap();
582 /// let dgram = UdpSocket::bind(address)?;
583 ///
584 /// // Wait until the dgram is readable...
585 ///
586 /// // Read from the dgram using a direct libc call, of course the
587 /// // `io::Read` implementation would be easier to use.
588 /// let mut buf = [0; 512];
589 /// let n = dgram.try_io(|| {
590 /// let buf_ptr = &mut buf as *mut _ as *mut _;
591 /// #[cfg(unix)]
592 /// let res = unsafe { libc::recv(dgram.as_raw_fd(), buf_ptr, buf.len(), 0) };
593 /// #[cfg(windows)]
594 /// let res = unsafe { libc::recvfrom(dgram.as_raw_socket() as usize, buf_ptr, buf.len() as i32, 0, std::ptr::null_mut(), std::ptr::null_mut()) };
595 /// if res != -1 {
596 /// Ok(res as usize)
597 /// } else {
598 /// // If EAGAIN or EWOULDBLOCK is set by libc::recv, the closure
599 /// // should return `WouldBlock` error.
600 /// Err(io::Error::last_os_error())
601 /// }
602 /// })?;
603 /// eprintln!("read {} bytes", n);
604 /// # Ok(())
605 /// # }
606 /// ```
607 pub fn try_io<F, T>(&self, f: F) -> io::Result<T>
608 where
609 F: FnOnce() -> io::Result<T>,
610 {
611 self.inner.do_io(|_| f())
612 }
613}
614
615impl event::Source for UdpSocket {
616 fn register(
617 &mut self,
618 registry: &Registry,
619 token: Token,
620 interests: Interest,
621 ) -> io::Result<()> {
622 self.inner.register(registry, token, interests)
623 }
624
625 fn reregister(
626 &mut self,
627 registry: &Registry,
628 token: Token,
629 interests: Interest,
630 ) -> io::Result<()> {
631 self.inner.reregister(registry, token, interests)
632 }
633
634 fn deregister(&mut self, registry: &Registry) -> io::Result<()> {
635 self.inner.deregister(registry)
636 }
637}
638
639impl fmt::Debug for UdpSocket {
640 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
641 self.inner.fmt(f)
642 }
643}
644
645#[cfg(unix)]
646impl IntoRawFd for UdpSocket {
647 fn into_raw_fd(self) -> RawFd {
648 self.inner.into_inner().into_raw_fd()
649 }
650}
651
652#[cfg(unix)]
653impl AsRawFd for UdpSocket {
654 fn as_raw_fd(&self) -> RawFd {
655 self.inner.as_raw_fd()
656 }
657}
658
659#[cfg(unix)]
660impl FromRawFd for UdpSocket {
661 /// Converts a `RawFd` to a `UdpSocket`.
662 ///
663 /// # Notes
664 ///
665 /// The caller is responsible for ensuring that the socket is in
666 /// non-blocking mode.
667 unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket {
668 UdpSocket::from_std(socket:FromRawFd::from_raw_fd(fd))
669 }
670}
671
672#[cfg(windows)]
673impl IntoRawSocket for UdpSocket {
674 fn into_raw_socket(self) -> RawSocket {
675 self.inner.into_inner().into_raw_socket()
676 }
677}
678
679#[cfg(windows)]
680impl AsRawSocket for UdpSocket {
681 fn as_raw_socket(&self) -> RawSocket {
682 self.inner.as_raw_socket()
683 }
684}
685
686#[cfg(windows)]
687impl FromRawSocket for UdpSocket {
688 /// Converts a `RawSocket` to a `UdpSocket`.
689 ///
690 /// # Notes
691 ///
692 /// The caller is responsible for ensuring that the socket is in
693 /// non-blocking mode.
694 unsafe fn from_raw_socket(socket: RawSocket) -> UdpSocket {
695 UdpSocket::from_std(FromRawSocket::from_raw_socket(socket))
696 }
697}
698