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 10 use crate::io_source::IoSource; 11 use crate::{event, sys, Interest, Registry, Token}; 12 13 use std::fmt; 14 use std::io; 15 use std::net; 16 use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; 17 #[cfg(unix)] 18 use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd}; 19 #[cfg(windows)] 20 use 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 /// # drop(buffer); // Silence unused assignment warning. 83 /// # return Ok(()); 84 /// } 85 /// _ => unreachable!() 86 /// } 87 /// } 88 /// } 89 /// # } 90 /// ``` 91 pub struct UdpSocket { 92 inner: IoSource<net::UdpSocket>, 93 } 94 95 impl 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 /// ``` bind(addr: SocketAddr) -> io::Result<UdpSocket>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. from_std(socket: net::UdpSocket) -> UdpSocket131 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 /// ``` local_addr(&self) -> io::Result<SocketAddr>160 pub fn local_addr(&self) -> io::Result<SocketAddr> { 161 self.inner.local_addr() 162 } 163 164 /// Sends data on the socket to the given address. On success, returns the 165 /// number of bytes written. 166 /// 167 /// Address type can be any implementor of `ToSocketAddrs` trait. See its 168 /// documentation for concrete examples. 169 /// 170 /// # Examples 171 /// 172 /// ```no_run 173 /// # use std::error::Error; 174 /// # fn main() -> Result<(), Box<dyn Error>> { 175 /// use mio::net::UdpSocket; 176 /// 177 /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?; 178 /// 179 /// // We must check if the socket is writable before calling send_to, 180 /// // or we could run into a WouldBlock error. 181 /// 182 /// let bytes_sent = socket.send_to(&[9; 9], "127.0.0.1:11100".parse()?)?; 183 /// assert_eq!(bytes_sent, 9); 184 /// # 185 /// # Ok(()) 186 /// # } 187 /// ``` send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result<usize>188 pub fn send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result<usize> { 189 self.inner.do_io(|inner| inner.send_to(buf, target)) 190 } 191 192 /// Receives data from the socket. On success, returns the number of bytes 193 /// read and the address from whence the data came. 194 /// 195 /// # Notes 196 /// 197 /// On Windows, if the data is larger than the buffer specified, the buffer 198 /// is filled with the first part of the data, and recv_from returns the error 199 /// WSAEMSGSIZE(10040). The excess data is lost. 200 /// Make sure to always use a sufficiently large buffer to hold the 201 /// maximum UDP packet size, which can be up to 65536 bytes in size. 202 /// 203 /// # Examples 204 /// 205 /// ```no_run 206 /// # use std::error::Error; 207 /// # 208 /// # fn main() -> Result<(), Box<dyn Error>> { 209 /// use mio::net::UdpSocket; 210 /// 211 /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?; 212 /// 213 /// // We must check if the socket is readable before calling recv_from, 214 /// // or we could run into a WouldBlock error. 215 /// 216 /// let mut buf = [0; 9]; 217 /// let (num_recv, from_addr) = socket.recv_from(&mut buf)?; 218 /// println!("Received {:?} -> {:?} bytes from {:?}", buf, num_recv, from_addr); 219 /// # 220 /// # Ok(()) 221 /// # } 222 /// ``` recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)>223 pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { 224 self.inner.do_io(|inner| inner.recv_from(buf)) 225 } 226 227 /// Receives data from the socket, without removing it from the input queue. 228 /// On success, returns the number of bytes read and the address from whence 229 /// the data came. 230 /// 231 /// # Notes 232 /// 233 /// On Windows, if the data is larger than the buffer specified, the buffer 234 /// is filled with the first part of the data, and peek_from returns the error 235 /// WSAEMSGSIZE(10040). The excess data is lost. 236 /// Make sure to always use a sufficiently large buffer to hold the 237 /// maximum UDP packet size, which can be up to 65536 bytes in size. 238 /// 239 /// # Examples 240 /// 241 /// ```no_run 242 /// # use std::error::Error; 243 /// # 244 /// # fn main() -> Result<(), Box<dyn Error>> { 245 /// use mio::net::UdpSocket; 246 /// 247 /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?; 248 /// 249 /// // We must check if the socket is readable before calling recv_from, 250 /// // or we could run into a WouldBlock error. 251 /// 252 /// let mut buf = [0; 9]; 253 /// let (num_recv, from_addr) = socket.peek_from(&mut buf)?; 254 /// println!("Received {:?} -> {:?} bytes from {:?}", buf, num_recv, from_addr); 255 /// # 256 /// # Ok(()) 257 /// # } 258 /// ``` peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)>259 pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { 260 self.inner.do_io(|inner| inner.peek_from(buf)) 261 } 262 263 /// Sends data on the socket to the address previously bound via connect(). On success, 264 /// returns the number of bytes written. send(&self, buf: &[u8]) -> io::Result<usize>265 pub fn send(&self, buf: &[u8]) -> io::Result<usize> { 266 self.inner.do_io(|inner| inner.send(buf)) 267 } 268 269 /// Receives data from the socket previously bound with connect(). On success, returns 270 /// the number of bytes read. 271 /// 272 /// # Notes 273 /// 274 /// On Windows, if the data is larger than the buffer specified, the buffer 275 /// is filled with the first part of the data, and recv returns the error 276 /// WSAEMSGSIZE(10040). The excess data is lost. 277 /// Make sure to always use a sufficiently large buffer to hold the 278 /// maximum UDP packet size, which can be up to 65536 bytes in size. recv(&self, buf: &mut [u8]) -> io::Result<usize>279 pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> { 280 self.inner.do_io(|inner| inner.recv(buf)) 281 } 282 283 /// Receives data from the socket, without removing it from the input queue. 284 /// On success, returns the number of bytes read. 285 /// 286 /// # Notes 287 /// 288 /// On Windows, if the data is larger than the buffer specified, the buffer 289 /// is filled with the first part of the data, and peek returns the error 290 /// WSAEMSGSIZE(10040). The excess data is lost. 291 /// Make sure to always use a sufficiently large buffer to hold the 292 /// maximum UDP packet size, which can be up to 65536 bytes in size. peek(&self, buf: &mut [u8]) -> io::Result<usize>293 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { 294 self.inner.do_io(|inner| inner.peek(buf)) 295 } 296 297 /// Connects the UDP socket setting the default destination for `send()` 298 /// and limiting packets that are read via `recv` from the address specified 299 /// in `addr`. connect(&self, addr: SocketAddr) -> io::Result<()>300 pub fn connect(&self, addr: SocketAddr) -> io::Result<()> { 301 self.inner.connect(addr) 302 } 303 304 /// Sets the value of the `SO_BROADCAST` option for this socket. 305 /// 306 /// When enabled, this socket is allowed to send packets to a broadcast 307 /// address. 308 /// 309 /// # Examples 310 /// 311 #[cfg_attr(feature = "os-poll", doc = "```")] 312 #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")] 313 /// # use std::error::Error; 314 /// # 315 /// # fn main() -> Result<(), Box<dyn Error>> { 316 /// use mio::net::UdpSocket; 317 /// 318 /// let broadcast_socket = UdpSocket::bind("127.0.0.1:0".parse()?)?; 319 /// if broadcast_socket.broadcast()? == false { 320 /// broadcast_socket.set_broadcast(true)?; 321 /// } 322 /// 323 /// assert_eq!(broadcast_socket.broadcast()?, true); 324 /// # 325 /// # Ok(()) 326 /// # } 327 /// ``` set_broadcast(&self, on: bool) -> io::Result<()>328 pub fn set_broadcast(&self, on: bool) -> io::Result<()> { 329 self.inner.set_broadcast(on) 330 } 331 332 /// Gets the value of the `SO_BROADCAST` option for this socket. 333 /// 334 /// For more information about this option, see 335 /// [`set_broadcast`][link]. 336 /// 337 /// [link]: #method.set_broadcast 338 /// 339 /// # Examples 340 /// 341 #[cfg_attr(feature = "os-poll", doc = "```")] 342 #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")] 343 /// # use std::error::Error; 344 /// # 345 /// # fn main() -> Result<(), Box<dyn Error>> { 346 /// use mio::net::UdpSocket; 347 /// 348 /// let broadcast_socket = UdpSocket::bind("127.0.0.1:0".parse()?)?; 349 /// assert_eq!(broadcast_socket.broadcast()?, false); 350 /// # 351 /// # Ok(()) 352 /// # } 353 /// ``` broadcast(&self) -> io::Result<bool>354 pub fn broadcast(&self) -> io::Result<bool> { 355 self.inner.broadcast() 356 } 357 358 /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket. 359 /// 360 /// If enabled, multicast packets will be looped back to the local socket. 361 /// Note that this may not have any affect on IPv6 sockets. set_multicast_loop_v4(&self, on: bool) -> io::Result<()>362 pub fn set_multicast_loop_v4(&self, on: bool) -> io::Result<()> { 363 self.inner.set_multicast_loop_v4(on) 364 } 365 366 /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket. 367 /// 368 /// For more information about this option, see 369 /// [`set_multicast_loop_v4`][link]. 370 /// 371 /// [link]: #method.set_multicast_loop_v4 multicast_loop_v4(&self) -> io::Result<bool>372 pub fn multicast_loop_v4(&self) -> io::Result<bool> { 373 self.inner.multicast_loop_v4() 374 } 375 376 /// Sets the value of the `IP_MULTICAST_TTL` option for this socket. 377 /// 378 /// Indicates the time-to-live value of outgoing multicast packets for 379 /// this socket. The default value is 1 which means that multicast packets 380 /// don't leave the local network unless explicitly requested. 381 /// 382 /// Note that this may not have any affect on IPv6 sockets. set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()>383 pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> { 384 self.inner.set_multicast_ttl_v4(ttl) 385 } 386 387 /// Gets the value of the `IP_MULTICAST_TTL` option for this socket. 388 /// 389 /// For more information about this option, see 390 /// [`set_multicast_ttl_v4`][link]. 391 /// 392 /// [link]: #method.set_multicast_ttl_v4 multicast_ttl_v4(&self) -> io::Result<u32>393 pub fn multicast_ttl_v4(&self) -> io::Result<u32> { 394 self.inner.multicast_ttl_v4() 395 } 396 397 /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket. 398 /// 399 /// Controls whether this socket sees the multicast packets it sends itself. 400 /// Note that this may not have any affect on IPv4 sockets. set_multicast_loop_v6(&self, on: bool) -> io::Result<()>401 pub fn set_multicast_loop_v6(&self, on: bool) -> io::Result<()> { 402 self.inner.set_multicast_loop_v6(on) 403 } 404 405 /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket. 406 /// 407 /// For more information about this option, see 408 /// [`set_multicast_loop_v6`][link]. 409 /// 410 /// [link]: #method.set_multicast_loop_v6 multicast_loop_v6(&self) -> io::Result<bool>411 pub fn multicast_loop_v6(&self) -> io::Result<bool> { 412 self.inner.multicast_loop_v6() 413 } 414 415 /// Sets the value for the `IP_TTL` option on this socket. 416 /// 417 /// This value sets the time-to-live field that is used in every packet sent 418 /// from this socket. 419 /// 420 /// # Examples 421 /// 422 #[cfg_attr(feature = "os-poll", doc = "```")] 423 #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")] 424 /// # use std::error::Error; 425 /// # 426 /// # fn main() -> Result<(), Box<dyn Error>> { 427 /// use mio::net::UdpSocket; 428 /// 429 /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?; 430 /// if socket.ttl()? < 255 { 431 /// socket.set_ttl(255)?; 432 /// } 433 /// 434 /// assert_eq!(socket.ttl()?, 255); 435 /// # 436 /// # Ok(()) 437 /// # } 438 /// ``` set_ttl(&self, ttl: u32) -> io::Result<()>439 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> { 440 self.inner.set_ttl(ttl) 441 } 442 443 /// Gets the value of the `IP_TTL` option for this socket. 444 /// 445 /// For more information about this option, see [`set_ttl`][link]. 446 /// 447 /// [link]: #method.set_ttl 448 /// 449 /// # Examples 450 /// 451 #[cfg_attr(feature = "os-poll", doc = "```")] 452 #[cfg_attr(not(feature = "os-poll"), doc = "```ignore")] 453 /// # use std::error::Error; 454 /// # 455 /// # fn main() -> Result<(), Box<dyn Error>> { 456 /// use mio::net::UdpSocket; 457 /// 458 /// let socket = UdpSocket::bind("127.0.0.1:0".parse()?)?; 459 /// socket.set_ttl(255)?; 460 /// 461 /// assert_eq!(socket.ttl()?, 255); 462 /// # 463 /// # Ok(()) 464 /// # } 465 /// ``` ttl(&self) -> io::Result<u32>466 pub fn ttl(&self) -> io::Result<u32> { 467 self.inner.ttl() 468 } 469 470 /// Executes an operation of the `IP_ADD_MEMBERSHIP` type. 471 /// 472 /// This function specifies a new multicast group for this socket to join. 473 /// The address must be a valid multicast address, and `interface` is the 474 /// address of the local interface with which the system should join the 475 /// multicast group. If it's equal to `INADDR_ANY` then an appropriate 476 /// interface is chosen by the system. 477 #[allow(clippy::trivially_copy_pass_by_ref)] join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()>478 pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> { 479 self.inner.join_multicast_v4(multiaddr, interface) 480 } 481 482 /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type. 483 /// 484 /// This function specifies a new multicast group for this socket to join. 485 /// The address must be a valid multicast address, and `interface` is the 486 /// index of the interface to join/leave (or 0 to indicate any interface). 487 #[allow(clippy::trivially_copy_pass_by_ref)] join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()>488 pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> { 489 self.inner.join_multicast_v6(multiaddr, interface) 490 } 491 492 /// Executes an operation of the `IP_DROP_MEMBERSHIP` type. 493 /// 494 /// For more information about this option, see 495 /// [`join_multicast_v4`][link]. 496 /// 497 /// [link]: #method.join_multicast_v4 498 #[allow(clippy::trivially_copy_pass_by_ref)] leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()>499 pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> { 500 self.inner.leave_multicast_v4(multiaddr, interface) 501 } 502 503 /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type. 504 /// 505 /// For more information about this option, see 506 /// [`join_multicast_v6`][link]. 507 /// 508 /// [link]: #method.join_multicast_v6 509 #[allow(clippy::trivially_copy_pass_by_ref)] leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()>510 pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> { 511 self.inner.leave_multicast_v6(multiaddr, interface) 512 } 513 514 /// Get the value of the `IPV6_V6ONLY` option on this socket. 515 #[allow(clippy::trivially_copy_pass_by_ref)] only_v6(&self) -> io::Result<bool>516 pub fn only_v6(&self) -> io::Result<bool> { 517 sys::udp::only_v6(&self.inner) 518 } 519 520 /// Get the value of the `SO_ERROR` option on this socket. 521 /// 522 /// This will retrieve the stored error in the underlying socket, clearing 523 /// the field in the process. This can be useful for checking errors between 524 /// calls. take_error(&self) -> io::Result<Option<io::Error>>525 pub fn take_error(&self) -> io::Result<Option<io::Error>> { 526 self.inner.take_error() 527 } 528 } 529 530 impl event::Source for UdpSocket { register( &mut self, registry: &Registry, token: Token, interests: Interest, ) -> io::Result<()>531 fn register( 532 &mut self, 533 registry: &Registry, 534 token: Token, 535 interests: Interest, 536 ) -> io::Result<()> { 537 self.inner.register(registry, token, interests) 538 } 539 reregister( &mut self, registry: &Registry, token: Token, interests: Interest, ) -> io::Result<()>540 fn reregister( 541 &mut self, 542 registry: &Registry, 543 token: Token, 544 interests: Interest, 545 ) -> io::Result<()> { 546 self.inner.reregister(registry, token, interests) 547 } 548 deregister(&mut self, registry: &Registry) -> io::Result<()>549 fn deregister(&mut self, registry: &Registry) -> io::Result<()> { 550 self.inner.deregister(registry) 551 } 552 } 553 554 impl fmt::Debug for UdpSocket { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result555 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 556 self.inner.fmt(f) 557 } 558 } 559 560 #[cfg(unix)] 561 impl IntoRawFd for UdpSocket { into_raw_fd(self) -> RawFd562 fn into_raw_fd(self) -> RawFd { 563 self.inner.into_inner().into_raw_fd() 564 } 565 } 566 567 #[cfg(unix)] 568 impl AsRawFd for UdpSocket { as_raw_fd(&self) -> RawFd569 fn as_raw_fd(&self) -> RawFd { 570 self.inner.as_raw_fd() 571 } 572 } 573 574 #[cfg(unix)] 575 impl FromRawFd for UdpSocket { 576 /// Converts a `RawFd` to a `UdpSocket`. 577 /// 578 /// # Notes 579 /// 580 /// The caller is responsible for ensuring that the socket is in 581 /// non-blocking mode. from_raw_fd(fd: RawFd) -> UdpSocket582 unsafe fn from_raw_fd(fd: RawFd) -> UdpSocket { 583 UdpSocket::from_std(FromRawFd::from_raw_fd(fd)) 584 } 585 } 586 587 #[cfg(windows)] 588 impl IntoRawSocket for UdpSocket { into_raw_socket(self) -> RawSocket589 fn into_raw_socket(self) -> RawSocket { 590 self.inner.into_inner().into_raw_socket() 591 } 592 } 593 594 #[cfg(windows)] 595 impl AsRawSocket for UdpSocket { as_raw_socket(&self) -> RawSocket596 fn as_raw_socket(&self) -> RawSocket { 597 self.inner.as_raw_socket() 598 } 599 } 600 601 #[cfg(windows)] 602 impl FromRawSocket for UdpSocket { 603 /// Converts a `RawSocket` to a `UdpSocket`. 604 /// 605 /// # Notes 606 /// 607 /// The caller is responsible for ensuring that the socket is in 608 /// non-blocking mode. from_raw_socket(socket: RawSocket) -> UdpSocket609 unsafe fn from_raw_socket(socket: RawSocket) -> UdpSocket { 610 UdpSocket::from_std(FromRawSocket::from_raw_socket(socket)) 611 } 612 } 613