1 // Copyright (c) 2023 Huawei Device Co., Ltd. 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 use std::fmt::Formatter; 15 use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr}; 16 use std::os::unix::io::AsRawFd; 17 use std::{fmt, io, net}; 18 19 use super::UdpSock; 20 use crate::source::Fd; 21 use crate::{Interest, Selector, Source, Token}; 22 23 /// UdpSocket. The bottom layer uses std::net::UdpSocket。 24 /// UdpSocket supports bind\connect\send\recv\send_to\recv_from\broadcast. 25 /// 26 /// # Examples 27 /// 28 /// ```rust 29 /// use std::io; 30 /// 31 /// use ylong_io::UdpSocket; 32 /// 33 /// async fn io_func() -> io::Result<()> { 34 /// let sender_addr = "127.0.0.1:8081".parse().unwrap(); 35 /// let receiver_addr = "127.0.0.1:8082".parse().unwrap(); 36 /// let mut sender = UdpSocket::bind(sender_addr)?; 37 /// let mut receiver = UdpSocket::bind(receiver_addr)?; 38 /// 39 /// let len = sender.send_to(b"Hello", receiver_addr)?; 40 /// println!("{:?} bytes sent", len); 41 /// 42 /// let mut buf = [0; 1024]; 43 /// let (len, addr) = receiver.recv_from(&mut buf)?; 44 /// println!("{:?} bytes received from {:?}", len, addr); 45 /// 46 /// let connected_sender = match sender.connect(receiver_addr) { 47 /// Ok(socket) => socket, 48 /// Err(e) => { 49 /// return Err(e); 50 /// } 51 /// }; 52 /// let connected_receiver = match receiver.connect(sender_addr) { 53 /// Ok(socket) => socket, 54 /// Err(e) => { 55 /// return Err(e); 56 /// } 57 /// }; 58 /// let len = connected_sender.send(b"Hello")?; 59 /// println!("{:?} bytes sent", len); 60 /// let len = connected_receiver.recv(&mut buf)?; 61 /// println!("{:?} bytes received from {:?}", len, sender_addr); 62 /// Ok(()) 63 /// } 64 /// ``` 65 pub struct UdpSocket { 66 pub(crate) inner: net::UdpSocket, 67 } 68 69 impl UdpSocket { 70 /// Creates a UDP socket from the given address. 71 /// return io::Error if errors happen. 72 /// 73 /// # Examples 74 /// 75 /// ```rust 76 /// use std::io; 77 /// 78 /// use ylong_io::UdpSocket; 79 /// 80 /// async fn io_func() -> io::Result<()> { 81 /// let addr = "127.0.0.1:8080".parse().unwrap(); 82 /// let mut sock = match UdpSocket::bind(addr) { 83 /// Ok(new_socket) => new_socket, 84 /// Err(e) => { 85 /// panic!("Failed to bind socket. {:?}", e); 86 /// } 87 /// }; 88 /// Ok(()) 89 /// } 90 /// ``` bind(addr: SocketAddr) -> io::Result<UdpSocket>91 pub fn bind(addr: SocketAddr) -> io::Result<UdpSocket> { 92 let socket = UdpSock::new_socket(addr)?; 93 socket.bind(addr) 94 } 95 96 /// Creates a new `UdpSocket` from a standard `net::UdpSocket`. 97 /// 98 /// This function is intended to be used to wrap a UDP socket from the 99 /// standard library in the io equivalent. The conversion assumes nothing 100 /// about the underlying socket; it is left up to the user to set it in 101 /// non-blocking mode. from_std(socket: net::UdpSocket) -> UdpSocket102 pub fn from_std(socket: net::UdpSocket) -> UdpSocket { 103 UdpSocket { inner: socket } 104 } 105 106 /// Returns the local address that this socket is bound to. 107 /// 108 /// # Examples 109 /// 110 /// ```rust 111 /// use std::io; 112 /// 113 /// use ylong_io::UdpSocket; 114 /// 115 /// async fn io_func() -> io::Result<()> { 116 /// let addr = "127.0.0.1:8080".parse().unwrap(); 117 /// let mut sock = UdpSocket::bind(addr)?; 118 /// let local_addr = sock.local_addr()?; 119 /// Ok(()) 120 /// } 121 /// ``` local_addr(&self) -> io::Result<SocketAddr>122 pub fn local_addr(&self) -> io::Result<SocketAddr> { 123 self.inner.local_addr() 124 } 125 126 /// Sets the value for the IP_TTL option on this socket. 127 /// 128 /// # Examples 129 /// 130 /// ```no_run 131 /// use ylong_io::UdpSocket; 132 /// 133 /// let sender_addr = "127.0.0.1:8081".parse().unwrap(); 134 /// let socket = UdpSocket::bind(sender_addr).expect("Bind Socket Failed!"); 135 /// socket.set_ttl(100).expect("set_ttl call failed"); 136 /// ``` set_ttl(&self, ttl: u32) -> io::Result<()>137 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> { 138 self.inner.set_ttl(ttl) 139 } 140 141 /// Sets the value for the IP_TTL option on this socket. 142 /// 143 /// # Examples 144 /// 145 /// ```no_run 146 /// use ylong_io::UdpSocket; 147 /// 148 /// let sender_addr = "127.0.0.1:8081".parse().unwrap(); 149 /// let socket = UdpSocket::bind(sender_addr).expect("Bind Socket Failed!"); 150 /// socket.set_ttl(100).expect("set_ttl call failed"); 151 /// assert_eq!(socket.ttl().unwrap(), 100); 152 /// ``` ttl(&self) -> io::Result<u32>153 pub fn ttl(&self) -> io::Result<u32> { 154 self.inner.ttl() 155 } 156 157 /// Sends data on the socket to the given address. On success, returns the 158 /// number of bytes written. 159 /// 160 /// # Return value 161 /// The function returns: 162 /// * `Ok(n)` n is the number of bytes sent. 163 /// * `Err(e)` if an error is encountered. 164 /// 165 /// # Examples 166 /// 167 /// ```rust 168 /// use std::io; 169 /// 170 /// use ylong_io::UdpSocket; 171 /// 172 /// async fn io_func() -> io::Result<()> { 173 /// let local_addr = "127.0.0.1:8080".parse().unwrap(); 174 /// let sock = UdpSocket::bind(local_addr)?; 175 /// let remote_addr = "127.0.0.1:8081".parse().unwrap(); 176 /// let len = sock.send_to(b"hello world", remote_addr)?; 177 /// println!("Sent {} bytes", len); 178 /// Ok(()) 179 /// } 180 /// ``` send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result<usize>181 pub fn send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result<usize> { 182 let inner = &self.inner; 183 inner.send_to(buf, target) 184 } 185 186 /// Receives a single datagram message on the socket. On success, returns 187 /// the number of bytes read and the origin. The function must be called 188 /// with valid byte array buf of sufficient size to hold the message bytes. 189 /// If a message is too long to fit in the supplied buffer, excess bytes may 190 /// be discarded. 191 /// 192 /// # Return value 193 /// The function returns: 194 /// * `Ok((n, addr))` n is the number of bytes received, addr is the address 195 /// of sender. 196 /// * `Err(e)` if an error is encountered. 197 /// 198 /// # Examples 199 /// 200 /// ```rust 201 /// use std::io; 202 /// 203 /// use ylong_io::UdpSocket; 204 /// 205 /// async fn io_func() -> io::Result<()> { 206 /// let local_addr = "127.0.0.1:8080".parse().unwrap(); 207 /// let sock = UdpSocket::bind(local_addr)?; 208 /// let mut recv_buf = [0_u8; 12]; 209 /// let (len, addr) = sock.recv_from(&mut recv_buf)?; 210 /// println!("received {:?} bytes from {:?}", len, addr); 211 /// Ok(()) 212 /// } 213 /// ``` recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)>214 pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { 215 let inner = &self.inner; 216 inner.recv_from(buf) 217 } 218 219 /// Receives single datagram on the socket from the remote address to which 220 /// it is connected, without removing the message from input queue. On 221 /// success, returns the number of bytes peeked. 222 /// 223 /// # Examples 224 /// 225 /// ```no_run 226 /// use ylong_io::UdpSocket; 227 /// 228 /// let sender_addr = "127.0.0.1:8081".parse().unwrap(); 229 /// 230 /// let socket = UdpSocket::bind(sender_addr).expect("couldn't bind to address"); 231 /// let mut buf = [0; 10]; 232 /// let (number_of_bytes, src_addr) = socket.peek_from(&mut buf).expect("Didn't receive data"); 233 /// let filled_buf = &mut buf[..number_of_bytes]; 234 /// ``` peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)>235 pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { 236 let inner = &self.inner; 237 inner.peek_from(buf) 238 } 239 240 /// Connects the UDP socket setting the default destination for send() 241 /// and limiting packets that are read via recv from the address specified 242 /// in addr. return io::Error if errors happen. 243 /// 244 /// # Examples 245 /// 246 /// ```rust 247 /// use std::io; 248 /// 249 /// use ylong_io::UdpSocket; 250 /// 251 /// async fn io_func() -> io::Result<()> { 252 /// let local_addr = "127.0.0.1:8080".parse().unwrap(); 253 /// let sock = UdpSocket::bind(local_addr)?; 254 /// let remote_addr = "127.0.0.1:8081".parse().unwrap(); 255 /// let connected_sock = match sock.connect(remote_addr) { 256 /// Ok(socket) => socket, 257 /// Err(e) => { 258 /// return Err(e); 259 /// } 260 /// }; 261 /// Ok(()) 262 /// } 263 /// ``` connect(self, addr: SocketAddr) -> io::Result<ConnectedUdpSocket>264 pub fn connect(self, addr: SocketAddr) -> io::Result<ConnectedUdpSocket> { 265 let socket = ConnectedUdpSocket::from_std(self.inner); 266 socket.inner.connect(addr)?; 267 Ok(socket) 268 } 269 270 /// Sets the value of the `SO_BROADCAST` option for this socket. 271 /// When enabled, this socket is allowed to send packets to a broadcast 272 /// address. 273 /// 274 /// # Examples 275 /// 276 /// ```rust 277 /// use std::io; 278 /// 279 /// use ylong_io::UdpSocket; 280 /// 281 /// async fn io_func() -> io::Result<()> { 282 /// let local_addr = "127.0.0.1:8080".parse().unwrap(); 283 /// let broadcast_socket = UdpSocket::bind(local_addr)?; 284 /// if broadcast_socket.broadcast()? == false { 285 /// broadcast_socket.set_broadcast(true)?; 286 /// } 287 /// assert_eq!(broadcast_socket.broadcast()?, true); 288 /// Ok(()) 289 /// } 290 /// ``` set_broadcast(&self, on: bool) -> io::Result<()>291 pub fn set_broadcast(&self, on: bool) -> io::Result<()> { 292 self.inner.set_broadcast(on) 293 } 294 295 /// Gets the value of the `SO_BROADCAST` option for this socket. 296 /// 297 /// # Examples 298 /// 299 /// ```rust 300 /// use std::io; 301 /// 302 /// use ylong_io::UdpSocket; 303 /// 304 /// async fn io_func() -> io::Result<()> { 305 /// let local_addr = "127.0.0.1:8080".parse().unwrap(); 306 /// let broadcast_socket = UdpSocket::bind(local_addr)?; 307 /// assert_eq!(broadcast_socket.broadcast()?, false); 308 /// Ok(()) 309 /// } 310 /// ``` broadcast(&self) -> io::Result<bool>311 pub fn broadcast(&self) -> io::Result<bool> { 312 self.inner.broadcast() 313 } 314 315 /// Gets the value of the SO_ERROR option on this socket. 316 /// This will retrieve the stored error in the underlying socket, clearing 317 /// the field in the process. This can be useful for checking errors between 318 /// calls. 319 /// 320 /// # Examples 321 /// 322 /// ```no_run 323 /// use ylong_io::UdpSocket; 324 /// 325 /// let addr = "127.0.0.1:34254".parse().unwrap(); 326 /// let socket = UdpSocket::bind(addr).expect("couldn't bind to address"); 327 /// match socket.take_error() { 328 /// Ok(Some(error)) => println!("UdpSocket error: {error:?}"), 329 /// Ok(None) => println!("No error"), 330 /// Err(error) => println!("UdpSocket.take_error failed: {error:?}"), 331 /// } 332 /// ``` take_error(&self) -> io::Result<Option<io::Error>>333 pub fn take_error(&self) -> io::Result<Option<io::Error>> { 334 self.inner.take_error() 335 } 336 337 /// Gets the value of the IP_MULTICAST_LOOP option for this socket. multicast_loop_v4(&self) -> io::Result<bool>338 pub fn multicast_loop_v4(&self) -> io::Result<bool> { 339 self.inner.multicast_loop_v4() 340 } 341 342 /// Sets the value of the IP_MULTICAST_LOOP option for this socket. 343 /// If enabled, multicast packets will be looped back to the local socket. 344 /// Note that this might not have any effect on IPv6 sockets. set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()>345 pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { 346 self.inner.set_multicast_loop_v4(multicast_loop_v4) 347 } 348 349 /// Gets the value of the IP_MULTICAST_TTL option for this socket. multicast_ttl_v4(&self) -> io::Result<u32>350 pub fn multicast_ttl_v4(&self) -> io::Result<u32> { 351 self.inner.multicast_ttl_v4() 352 } 353 354 /// Sets the value of the IP_MULTICAST_TTL option for this socket. 355 /// Indicates the time-to-live value of outgoing multicast packets for this 356 /// socket. The default value is 1 which means that multicast packets don't 357 /// leave the local network unless explicitly requested. Note that this 358 /// might not have any effect on IPv6 sockets. set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()>359 pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { 360 self.inner.set_multicast_ttl_v4(multicast_ttl_v4) 361 } 362 363 /// Gets the value of the IPV6_MULTICAST_LOOP option for this socket. multicast_loop_v6(&self) -> io::Result<bool>364 pub fn multicast_loop_v6(&self) -> io::Result<bool> { 365 self.inner.multicast_loop_v6() 366 } 367 368 /// Sets the value of the IPV6_MULTICAST_LOOP option for this socket. 369 /// Controls whether this socket sees the multicast packets it sends itself. 370 /// Note that this might not have any affect on IPv4 sockets. set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()>371 pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> { 372 self.inner.set_multicast_loop_v6(multicast_loop_v6) 373 } 374 375 /// Executes an operation of the IP_ADD_MEMBERSHIP type. join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()>376 pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> { 377 self.inner.join_multicast_v4(multiaddr, interface) 378 } 379 380 /// Executes an operation of the IPV6_ADD_MEMBERSHIP type. join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()>381 pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> { 382 self.inner.join_multicast_v6(multiaddr, interface) 383 } 384 385 /// Executes an operation of the IP_DROP_MEMBERSHIP type. leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()>386 pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> { 387 self.inner.leave_multicast_v4(multiaddr, interface) 388 } 389 390 /// Executes an operation of the IPV6_DROP_MEMBERSHIP type. leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()>391 pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> { 392 self.inner.leave_multicast_v6(multiaddr, interface) 393 } 394 } 395 396 /// An already connected, non-blocking UdpSocket 397 pub struct ConnectedUdpSocket { 398 pub(crate) inner: net::UdpSocket, 399 } 400 401 impl ConnectedUdpSocket { 402 /// Creates a new `UdpSocket` from a standard `net::UdpSocket`. 403 /// 404 /// This function is intended to be used to wrap a UDP socket from the 405 /// standard library in the io equivalent. The conversion assumes nothing 406 /// about the underlying socket; it is left up to the user to set it in 407 /// non-blocking mode. from_std(socket: net::UdpSocket) -> ConnectedUdpSocket408 pub fn from_std(socket: net::UdpSocket) -> ConnectedUdpSocket { 409 ConnectedUdpSocket { inner: socket } 410 } 411 412 /// Returns the local address that this socket is bound to. 413 /// 414 /// # Examples 415 /// 416 /// ```rust 417 /// use std::io; 418 /// 419 /// use ylong_io::UdpSocket; 420 /// 421 /// async fn io_func() -> io::Result<()> { 422 /// let addr = "127.0.0.1:8080".parse().unwrap(); 423 /// let mut sock = UdpSocket::bind(addr)?; 424 /// let remote_addr = "127.0.0.1:8081".parse().unwrap(); 425 /// let connected_sock = match sock.connect(remote_addr) { 426 /// Ok(socket) => socket, 427 /// Err(e) => { 428 /// return Err(e); 429 /// } 430 /// }; 431 /// let local_addr = connected_sock.local_addr()?; 432 /// Ok(()) 433 /// } 434 /// ``` local_addr(&self) -> io::Result<SocketAddr>435 pub fn local_addr(&self) -> io::Result<SocketAddr> { 436 self.inner.local_addr() 437 } 438 439 /// Returns the socket address of the remote peer this socket was connected 440 /// to. 441 /// 442 /// # Examples 443 /// 444 /// ```rust 445 /// use std::io; 446 /// 447 /// use ylong_io::UdpSocket; 448 /// 449 /// async fn io_func() -> io::Result<()> { 450 /// let addr = "127.0.0.1:8080".parse().unwrap(); 451 /// let peer_addr = "127.0.0.1:8081".parse().unwrap(); 452 /// let mut sock = UdpSocket::bind(addr)?; 453 /// let connected_sock = match sock.connect(peer_addr) { 454 /// Ok(socket) => socket, 455 /// Err(e) => { 456 /// return Err(e); 457 /// } 458 /// }; 459 /// assert_eq!(connected_sock.peer_addr()?, peer_addr); 460 /// Ok(()) 461 /// } 462 /// ``` peer_addr(&self) -> io::Result<SocketAddr>463 pub fn peer_addr(&self) -> io::Result<SocketAddr> { 464 self.inner.peer_addr() 465 } 466 467 /// Sets the value for the IP_TTL option on this socket. 468 /// 469 /// # Examples 470 /// 471 /// ```no_run 472 /// use ylong_io::UdpSocket; 473 /// 474 /// let sender_addr = "127.0.0.1:8081".parse().unwrap(); 475 /// let socket = UdpSocket::bind(sender_addr).expect("Bind Socket Failed!"); 476 /// let receiver_addr = "127.0.0.1:8081".parse().unwrap(); 477 /// let connect_socket = socket 478 /// .connect(receiver_addr) 479 /// .expect("Connect Socket Failed!"); 480 /// connect_socket.set_ttl(100).expect("set_ttl call failed"); 481 /// ``` set_ttl(&self, ttl: u32) -> io::Result<()>482 pub fn set_ttl(&self, ttl: u32) -> io::Result<()> { 483 self.inner.set_ttl(ttl) 484 } 485 486 /// Sets the value for the IP_TTL option on this socket. 487 /// 488 /// # Examples 489 /// 490 /// ```no_run 491 /// use ylong_io::UdpSocket; 492 /// 493 /// let sender_addr = "127.0.0.1:8081".parse().unwrap(); 494 /// let socket = UdpSocket::bind(sender_addr).expect("Bind Socket Failed!"); 495 /// let receiver_addr = "127.0.0.1:8081".parse().unwrap(); 496 /// let connect_socket = socket 497 /// .connect(receiver_addr) 498 /// .expect("Connect Socket Failed!"); 499 /// connect_socket.set_ttl(100).expect("set_ttl call failed"); 500 /// assert_eq!(connect_socket.ttl().unwrap(), 100); 501 /// ``` ttl(&self) -> io::Result<u32>502 pub fn ttl(&self) -> io::Result<u32> { 503 self.inner.ttl() 504 } 505 506 /// Sends data on the socket to the remote address that the socket is 507 /// connected to. The connect method will connect this socket to a 508 /// remote address. This method will fail if the socket is not 509 /// connected. 510 /// 511 /// # Return 512 /// On success, the number of bytes sent is returned, otherwise, the 513 /// encountered error is returned. 514 /// 515 /// # Examples 516 /// 517 /// ```rust 518 /// use std::io; 519 /// 520 /// use ylong_io::UdpSocket; 521 /// 522 /// async fn io_func() -> io::Result<()> { 523 /// let local_addr = "127.0.0.1:8080".parse().unwrap(); 524 /// let sock = UdpSocket::bind(local_addr)?; 525 /// let remote_addr = "127.0.0.1:8081".parse().unwrap(); 526 /// let connected_sock = match sock.connect(remote_addr) { 527 /// Ok(socket) => socket, 528 /// Err(e) => { 529 /// return Err(e); 530 /// } 531 /// }; 532 /// connected_sock.send(b"Hello")?; 533 /// Ok(()) 534 /// } 535 /// ``` send(&self, buf: &[u8]) -> io::Result<usize>536 pub fn send(&self, buf: &[u8]) -> io::Result<usize> { 537 let inner = &self.inner; 538 inner.send(buf) 539 } 540 541 /// Receives a single datagram message on the socket from the remote address 542 /// to which it is connected. On success, returns the number of bytes read. 543 /// The function must be called with valid byte array buf of sufficient size 544 /// to hold the message bytes. If a message is too long to fit in the 545 /// supplied buffer, excess bytes may be discarded. The connect method 546 /// will connect this socket to a remote address. This method will fail 547 /// if the socket is not connected. 548 /// 549 /// # Return value 550 /// The function returns: 551 /// * `Ok(n)` n is is the number of bytes received 552 /// * `Err(e)` if an error is encountered. 553 /// 554 /// # Examples 555 /// 556 /// ```rust 557 /// use std::io; 558 /// 559 /// use ylong_io::UdpSocket; 560 /// 561 /// async fn io_func() -> io::Result<()> { 562 /// let local_addr = "127.0.0.1:8080".parse().unwrap(); 563 /// let sock = UdpSocket::bind(local_addr)?; 564 /// let remote_addr = "127.0.0.1:8081".parse().unwrap(); 565 /// let connected_sock = match sock.connect(remote_addr) { 566 /// Ok(socket) => socket, 567 /// Err(e) => { 568 /// return Err(e); 569 /// } 570 /// }; 571 /// let mut recv_buf = [0_u8; 12]; 572 /// let n = connected_sock.recv(&mut recv_buf[..])?; 573 /// println!("received {} bytes {:?}", n, &recv_buf[..n]); 574 /// Ok(()) 575 /// } 576 /// ``` recv(&self, buf: &mut [u8]) -> io::Result<usize>577 pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> { 578 let inner = &self.inner; 579 inner.recv(buf) 580 } 581 582 /// Receives single datagram on the socket from the remote address to which 583 /// it is connected, without removing the message from input queue. On 584 /// success, returns the number of bytes peeked. 585 /// 586 /// # Examples 587 /// 588 /// ```no_run 589 /// use ylong_io::UdpSocket; 590 /// 591 /// let sender_addr = "127.0.0.1:8081".parse().unwrap(); 592 /// let receiver_addr = "127.0.0.1:8082".parse().unwrap(); 593 /// 594 /// let socket = UdpSocket::bind(sender_addr).expect("couldn't bind to address"); 595 /// let connect_socket = socket 596 /// .connect(receiver_addr) 597 /// .expect("connect function failed"); 598 /// let mut buf = [0; 10]; 599 /// match connect_socket.peek(&mut buf) { 600 /// Ok(received) => println!("received {received} bytes"), 601 /// Err(e) => println!("peek function failed: {e:?}"), 602 /// } 603 /// ``` peek(&self, buf: &mut [u8]) -> io::Result<usize>604 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> { 605 let inner = &self.inner; 606 inner.peek(buf) 607 } 608 609 /// Sets the value of the `SO_BROADCAST` option for this socket. 610 /// When enabled, this socket is allowed to send packets to a broadcast 611 /// address. 612 /// 613 /// # Examples 614 /// 615 /// ```rust 616 /// use std::io; 617 /// 618 /// use ylong_io::UdpSocket; 619 /// 620 /// async fn io_func() -> io::Result<()> { 621 /// let local_addr = "127.0.0.1:8080".parse().unwrap(); 622 /// let receiver_addr = "127.0.0.1:8081".parse().unwrap(); 623 /// let socket = UdpSocket::bind(local_addr)?; 624 /// let connect_socket = socket 625 /// .connect(receiver_addr) 626 /// .expect("connect function failed"); 627 /// if connect_socket.broadcast()? == false { 628 /// connect_socket.set_broadcast(true)?; 629 /// } 630 /// assert_eq!(connect_socket.broadcast()?, true); 631 /// Ok(()) 632 /// } 633 /// ``` set_broadcast(&self, on: bool) -> io::Result<()>634 pub fn set_broadcast(&self, on: bool) -> io::Result<()> { 635 self.inner.set_broadcast(on) 636 } 637 638 /// Gets the value of the `SO_BROADCAST` option for this socket. 639 /// 640 /// # Examples 641 /// 642 /// ```rust 643 /// use std::io; 644 /// 645 /// use ylong_io::UdpSocket; 646 /// 647 /// async fn io_func() -> io::Result<()> { 648 /// let local_addr = "127.0.0.1:8080".parse().unwrap(); 649 /// let receiver_addr = "127.0.0.1:8081".parse().unwrap(); 650 /// let socket = UdpSocket::bind(local_addr)?; 651 /// let connect_socket = socket 652 /// .connect(receiver_addr) 653 /// .expect("connect function failed"); 654 /// assert_eq!(connect_socket.broadcast()?, false); 655 /// Ok(()) 656 /// } 657 /// ``` broadcast(&self) -> io::Result<bool>658 pub fn broadcast(&self) -> io::Result<bool> { 659 self.inner.broadcast() 660 } 661 662 /// Gets the value of the IP_MULTICAST_LOOP option for this socket. multicast_loop_v4(&self) -> io::Result<bool>663 pub fn multicast_loop_v4(&self) -> io::Result<bool> { 664 self.inner.multicast_loop_v4() 665 } 666 667 /// Sets the value of the IP_MULTICAST_LOOP option for this socket. 668 /// If enabled, multicast packets will be looped back to the local socket. 669 /// Note that this might not have any effect on IPv6 sockets. set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()>670 pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { 671 self.inner.set_multicast_loop_v4(multicast_loop_v4) 672 } 673 674 /// Gets the value of the IP_MULTICAST_TTL option for this socket. multicast_ttl_v4(&self) -> io::Result<u32>675 pub fn multicast_ttl_v4(&self) -> io::Result<u32> { 676 self.inner.multicast_ttl_v4() 677 } 678 679 /// Sets the value of the IP_MULTICAST_TTL option for this socket. 680 /// Indicates the time-to-live value of outgoing multicast packets for this 681 /// socket. The default value is 1 which means that multicast packets don't 682 /// leave the local network unless explicitly requested. Note that this 683 /// might not have any effect on IPv6 sockets. set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()>684 pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { 685 self.inner.set_multicast_ttl_v4(multicast_ttl_v4) 686 } 687 688 /// Gets the value of the IPV6_MULTICAST_LOOP option for this socket. multicast_loop_v6(&self) -> io::Result<bool>689 pub fn multicast_loop_v6(&self) -> io::Result<bool> { 690 self.inner.multicast_loop_v6() 691 } 692 693 /// Sets the value of the IPV6_MULTICAST_LOOP option for this socket. 694 /// Controls whether this socket sees the multicast packets it sends itself. 695 /// Note that this might not have any affect on IPv4 sockets. set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()>696 pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> { 697 self.inner.set_multicast_loop_v6(multicast_loop_v6) 698 } 699 700 /// Executes an operation of the IP_ADD_MEMBERSHIP type. join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()>701 pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> { 702 self.inner.join_multicast_v4(multiaddr, interface) 703 } 704 705 /// Executes an operation of the IPV6_ADD_MEMBERSHIP type. join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()>706 pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> { 707 self.inner.join_multicast_v6(multiaddr, interface) 708 } 709 710 /// Executes an operation of the IP_DROP_MEMBERSHIP type. leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()>711 pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> { 712 self.inner.leave_multicast_v4(multiaddr, interface) 713 } 714 715 /// Executes an operation of the IPV6_DROP_MEMBERSHIP type. leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()>716 pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> { 717 self.inner.leave_multicast_v6(multiaddr, interface) 718 } 719 720 /// Gets the value of the SO_ERROR option on this socket. 721 /// This will retrieve the stored error in the underlying socket, clearing 722 /// the field in the process. This can be useful for checking errors between 723 /// calls. 724 /// 725 /// # Examples 726 /// 727 /// ```no_run 728 /// use ylong_io::UdpSocket; 729 /// 730 /// let addr = "127.0.0.1:34253".parse().unwrap(); 731 /// let receiver_addr = "127.0.0.1:34254".parse().unwrap(); 732 /// let socket = UdpSocket::bind(addr).expect("couldn't bind to address"); 733 /// let connected_sender = socket 734 /// .connect(receiver_addr) 735 /// .expect("connect function failed"); 736 /// match connected_sender.take_error() { 737 /// Ok(Some(error)) => println!("ConnectedUdpSocket error: {error:?}"), 738 /// Ok(None) => println!("No error"), 739 /// Err(error) => println!("ConnectedUdpSocket.take_error failed: {error:?}"), 740 /// } 741 /// ``` take_error(&self) -> io::Result<Option<io::Error>>742 pub fn take_error(&self) -> io::Result<Option<io::Error>> { 743 self.inner.take_error() 744 } 745 } 746 747 impl fmt::Debug for UdpSocket { fmt(&self, f: &mut Formatter<'_>) -> fmt::Result748 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 749 self.inner.fmt(f) 750 } 751 } 752 753 impl fmt::Debug for ConnectedUdpSocket { fmt(&self, f: &mut Formatter<'_>) -> fmt::Result754 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { 755 self.inner.fmt(f) 756 } 757 } 758 759 impl Source for UdpSocket { register( &mut self, selector: &Selector, token: Token, interests: Interest, ) -> io::Result<()>760 fn register( 761 &mut self, 762 selector: &Selector, 763 token: Token, 764 interests: Interest, 765 ) -> io::Result<()> { 766 selector.register(self.as_raw_fd(), token, interests) 767 } 768 reregister( &mut self, selector: &Selector, token: Token, interests: Interest, ) -> io::Result<()>769 fn reregister( 770 &mut self, 771 selector: &Selector, 772 token: Token, 773 interests: Interest, 774 ) -> io::Result<()> { 775 selector.reregister(self.as_raw_fd(), token, interests) 776 } 777 deregister(&mut self, selector: &Selector) -> io::Result<()>778 fn deregister(&mut self, selector: &Selector) -> io::Result<()> { 779 selector.deregister(self.as_raw_fd()) 780 } 781 as_raw_fd(&self) -> Fd782 fn as_raw_fd(&self) -> Fd { 783 self.inner.as_raw_fd() 784 } 785 } 786 787 impl Source for ConnectedUdpSocket { register( &mut self, selector: &Selector, token: Token, interests: Interest, ) -> io::Result<()>788 fn register( 789 &mut self, 790 selector: &Selector, 791 token: Token, 792 interests: Interest, 793 ) -> io::Result<()> { 794 selector.register(self.as_raw_fd(), token, interests) 795 } 796 reregister( &mut self, selector: &Selector, token: Token, interests: Interest, ) -> io::Result<()>797 fn reregister( 798 &mut self, 799 selector: &Selector, 800 token: Token, 801 interests: Interest, 802 ) -> io::Result<()> { 803 selector.reregister(self.as_raw_fd(), token, interests) 804 } 805 deregister(&mut self, selector: &Selector) -> io::Result<()>806 fn deregister(&mut self, selector: &Selector) -> io::Result<()> { 807 selector.deregister(self.as_raw_fd()) 808 } 809 as_raw_fd(&self) -> Fd810 fn as_raw_fd(&self) -> Fd { 811 self.inner.as_raw_fd() 812 } 813 } 814