use std::{ net::{ Ipv4Addr, SocketAddrV4, }, sync::Arc, }; use tokio::{ net::{ TcpListener, TcpStream, UdpSocket, }, spawn, }; use crate::loops; pub async fn main () -> anyhow::Result <()> { let tcp_listener = TcpListener::bind ((Ipv4Addr::UNSPECIFIED, crate::PORT_2)).await?; loop { let (conn, _peer_addr) = tcp_listener.accept ().await?; spawn (handle_connection (conn)); } } async fn handle_connection (conn: TcpStream) -> anyhow::Result <()> { let udp_sock = UdpSocket::bind (SocketAddrV4::new (Ipv4Addr::UNSPECIFIED, 0)).await?; udp_sock.connect ((Ipv4Addr::LOCALHOST, crate::PORT_3)).await?; let (tcp_read, tcp_write) = conn.into_split (); let rx_task; let tx_task; { let udp_sock = Arc::new (udp_sock); rx_task = spawn (loops::rx (Arc::clone (&udp_sock), tcp_read)); tx_task = spawn (loops::tx (Arc::clone (&udp_sock), tcp_write)); } tokio::select! { _val = tx_task => { println! ("server_handle_connection: tx_task exited, exiting"); } _val = rx_task => { println! ("server_handle_connection: rx_task exited, exiting"); } } Ok (()) }