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