use tokio::spawn as go; use tokio::io::BufReader; use tokio::io::AsyncBufReadExt; use tokio::io::AsyncWriteExt; use tokio::net::TcpListener; use tokio::net::TcpStream; #[tokio::main] async fn main(){ // listening on tcp://0.0.0.0:8080 let ln = TcpListener::bind("0.0.0.0:8080").await.unwrap(); println!("listening on {:?}", ln.local_addr().unwrap()); // assign a unique id to each incoming connection for client_id in 0.. { if let Ok((stream, addr)) = ln.accept().await { println!("client[{}] connected from {:?}", client_id, addr); // handle the connection go(echo(stream, client_id)); } } } async fn echo(stream : TcpStream, client_id: u32){ // split the stream into rd (reader) and wr (writer) let (rd, mut wr) = stream.into_split(); // create a scanner from rd let mut scanner = BufReader::new(rd).lines(); // for each line, do ... loop { // get line : Option> let line = scanner.next_line().await; match line { // if ok, echo/print line Ok(Some(line)) => { // echo back to client if let Err(e) = wr.write_all(format!("{}\n", line).as_bytes()).await { // client write error println!("client[{}] disconnected: write: {}", client_id, e); break; }; // server-side log println!("client[{}]: {}", client_id, line); }, // if non-EOF error Err(e) => { println!("client[{}] disconnected: read: {:?}", client_id, e); break; }, // if EOF Ok(None) => { println!("client[{}] disconnected: read: EOF", client_id); break; }, }; } }