use std::io; use std::net::SocketAddr; use std::sync::atomic::{AtomicU64, Ordering}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::{TcpListener, TcpStream}; use local_ip_address::local_ip; use std::net::{IpAddr, Ipv4Addr}; static NEXT_CONNECTION_ID: AtomicU64 = AtomicU64::new(1); #[tokio::main] async fn main() -> io::Result<()> { let my_ip: IpAddr = local_ip().unwrap_or(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1))); let listener = TcpListener::bind((my_ip,32768)).await?; println!("Сервер слушает {}:32768",my_ip); loop { let (stream, client_addr) = listener.accept().await?; let connection_id = NEXT_CONNECTION_ID.fetch_add(1, Ordering::Relaxed); let connection = Connection::new( connection_id, client_addr, stream, ); tokio::spawn(async move { if let Err(error) = connection.run().await { eprintln!( "Обработчик {connection_id}: ошибка: {error}" ); } }); } } struct Connection { id: u64, client_addr: SocketAddr, stream: TcpStream, message_count: u64, } impl Connection { fn new( id: u64, client_addr: SocketAddr, stream: TcpStream, ) -> Self { Self { id, client_addr, stream, message_count: 0, } } async fn run(mut self) -> io::Result<()> { println!( "Обработчик {} создан для {}", self.id, self.client_addr ); let mut buffer = [0_u8; 1024]; loop { let bytes_read = self.stream.read(&mut buffer).await?; if bytes_read == 0 { println!( "Обработчик {}: клиент {} отключился", self.id, self.client_addr ); return Ok(()); } self.message_count += 1; let received = String::from_utf8_lossy(&buffer[..bytes_read]); println!( "Обработчик {}: сообщение №{}: {:?}", self.id, self.message_count, received ); let response = format!( "Обработчик {}: сообщение №{}: {}\n", self.id, self.message_count, received ); self.stream.write_all(response.as_bytes()).await?; } } }