Created
February 12, 2022 23:03
-
-
Save WhiteGrouse/f6ac6ea393f22e82edcf5c8fdf1bc79a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use std::time::Duration; | |
| use std::sync::atomic::{AtomicBool, Ordering}; | |
| use async_std::io::{self, ErrorKind}; | |
| use async_std::net::{ToSocketAddrs, UdpSocket}; | |
| use async_std::sync::{Arc, Weak}; | |
| use async_std::channel::{bounded, Sender, Receiver}; | |
| use async_std::task::{self, JoinHandle}; | |
| struct Listener { | |
| recv_task: Option<JoinHandle<()>>, | |
| shutdown: Arc<AtomicBool>, | |
| } | |
| impl Listener { | |
| fn new(socket: Arc<UdpSocket>) -> Listener { | |
| let shutdown = Arc::new(AtomicBool::new(false)); | |
| let recv_task = Some(task::spawn(Self::receiver(shutdown.clone(), socket))); | |
| Listener { | |
| recv_task, | |
| shutdown, | |
| } | |
| } | |
| async fn receiver(shutdown: Arc<AtomicBool>, socket: Arc<UdpSocket>) { | |
| let mut buffer = Vec::with_capacity(4096); | |
| unsafe { buffer.set_len(4096); } | |
| loop { | |
| let (size, remote) = match io::timeout(Duration::from_millis(500), socket.recv_from(&mut buffer)).await { | |
| Ok(v) => v, | |
| Err(e) if e.kind() == ErrorKind::TimedOut => { | |
| if shutdown.load(Ordering::Relaxed) { break; } | |
| else { println!("timedout. retrying..."); continue; } | |
| }, | |
| Err(e) => panic!("Error at receiver(9: {:?}", e), | |
| }; | |
| //handle packet | |
| } | |
| } | |
| } | |
| impl Drop for Listener { | |
| fn drop(&mut self) { | |
| println!("sending shutdown..."); | |
| self.shutdown.store(true, Ordering::Relaxed); | |
| println!("waiting for the receiver to stop..."); | |
| task::block_on(self.recv_task.take().unwrap()); | |
| println!("bye..."); | |
| } | |
| } | |
| #[async_std::main] | |
| async fn main() { | |
| let socket = Arc::new(UdpSocket::bind("0.0.0.0:19132").await.unwrap()); | |
| let listener = Listener::new(socket.clone()); | |
| println!("sleeping..."); | |
| task::sleep(Duration::from_secs(3)).await; | |
| println!("let's drop."); | |
| drop(listener); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment