moirai_async/net/
socket.rs1use moirai_pal::net::AsyncUdpSocket;
2use std::io;
3use std::net::SocketAddr;
4use std::sync::Arc;
5
6use crate::net::types::{UdpConfig, UdpSocketStats, UdpStats};
7
8pub struct UdpSocket {
10 inner: AsyncUdpSocket,
11 stats: Arc<UdpStats>,
12 config: UdpConfig,
13}
14
15impl UdpSocket {
16 pub async fn bind(addr: &str) -> io::Result<Self> {
18 Self::bind_with_config(addr, UdpConfig::default()).await
19 }
20
21 pub async fn bind_with_config(addr: &str, config: UdpConfig) -> io::Result<Self> {
23 let addr_parsed = crate::net::resolve::resolve(addr).await?.first();
24 let inner = AsyncUdpSocket::bind(addr_parsed).await?;
25 if config.broadcast {
26 inner.set_broadcast(true)?;
27 }
28
29 Ok(Self {
30 inner,
31 stats: Arc::new(UdpStats::default()),
32 config,
33 })
34 }
35
36 pub async fn send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result<usize> {
38 let bytes_sent = self.inner.send_to(buf, target).await?;
39 self.stats
40 .packets_sent
41 .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
42 self.stats
43 .bytes_sent
44 .fetch_add(bytes_sent as u64, std::sync::atomic::Ordering::Relaxed);
45 Ok(bytes_sent)
46 }
47
48 pub async fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
50 let (bytes_received, addr) = self.inner.recv_from(buf).await?;
51 self.stats
52 .packets_received
53 .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
54 self.stats
55 .bytes_received
56 .fetch_add(bytes_received as u64, std::sync::atomic::Ordering::Relaxed);
57 Ok((bytes_received, addr))
58 }
59
60 pub fn stats(&self) -> UdpSocketStats {
62 UdpSocketStats {
63 packets_sent: self
64 .stats
65 .packets_sent
66 .load(std::sync::atomic::Ordering::Relaxed),
67 packets_received: self
68 .stats
69 .packets_received
70 .load(std::sync::atomic::Ordering::Relaxed),
71 bytes_sent: self
72 .stats
73 .bytes_sent
74 .load(std::sync::atomic::Ordering::Relaxed),
75 bytes_received: self
76 .stats
77 .bytes_received
78 .load(std::sync::atomic::Ordering::Relaxed),
79 }
80 }
81
82 pub fn local_addr(&self) -> io::Result<SocketAddr> {
84 self.inner.local_addr()
85 }
86
87 pub fn config(&self) -> &UdpConfig {
89 &self.config
90 }
91}