use foxtrot::{ io::{Nonblocking, Readiness}, net::TcpListener, Async, }; use join_all::join_all; use read_write_buf::ReadWriteBuf; async fn echo(port: u16) -> Result<(), foxtrot::Error> { let mut listener = Async::::bind(([127, 0, 0, 1], port)).await?; println!("bound listener"); loop { let (mut stream, _addr) = listener.accept().await?; println!("Accepted connection"); let mut interests = Readiness::read(); let mut ring_buf = ReadWriteBuf::<10>::new(); 'l2: loop { let readiness = stream.ready(interests).await?; if readiness.is_hangup() { break; } if readiness.is_read() { while let Some(buf) = ring_buf.for_reading() { match stream.read_nonblocking(buf)? { Nonblocking::Ready(n) if n > 0 => { let should_break = n < buf.len(); ring_buf.advance_read(n); if should_break { break; } } Nonblocking::Ready(_) if ring_buf.is_empty() => break 'l2, Nonblocking::Ready(_) | Nonblocking::WouldBlock => break, } } if !ring_buf.is_empty() { interests = Readiness::read() | Readiness::write(); } } if readiness.is_write() { while let Some(buf) = ring_buf.for_writing() { match stream.write_nonblocking(buf)? { Nonblocking::Ready(n) => { ring_buf.advance_write(n); if ring_buf.is_empty() { interests = Readiness::read(); } } Nonblocking::WouldBlock => {} } } } } println!("Connection closed"); } } fn main() -> Result<(), foxtrot::Error> { foxtrot::block_on(async move { for res in join_all(vec![Box::pin(echo(4444)), Box::pin(echo(4445))]).await { res?; } Ok(()) })? }