Add per-connection state and async handlers

This commit is contained in:
Stanislav N Mikhailov
2026-07-10 22:52:11 +03:00
parent b7b028fc92
commit d921be7696
+74 -11
View File
@@ -1,40 +1,103 @@
use std::io;
use std::net::SocketAddr;
use std::sync::atomic::{AtomicU64, Ordering};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::{TcpListener, TcpStream};
static NEXT_CONNECTION_ID: AtomicU64 = AtomicU64::new(1);
#[tokio::main]
async fn main() -> io::Result<()> {
let listener = TcpListener::bind("192.168.1.152:32768").await?;
println!("Сервер слушает 127.0.0.1:32768");
println!("Сервер слушает 192.168.1.152:32768");
loop {
let (stream, client_addr) = listener.accept().await?;
println!("Подключился клиент: {}", client_addr);
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) = handle_client(stream).await {
eprintln!("Ошибка клиента {client_addr}: {error}");
if let Err(error) = connection.run().await {
eprintln!(
"Обработчик {connection_id}: ошибка: {error}"
);
}
println!("Клиент {client_addr} отключился");
});
}
}
async fn handle_client(mut stream:TcpStream) -> io::Result<()> {
let mut buffer = [0_u8; 3];
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 = stream.read(&mut buffer).await?;
let bytes_read = self.stream.read(&mut buffer).await?;
if bytes_read == 0 {
println!(
"Обработчик {}: клиент {} отключился",
self.id,
self.client_addr
);
return Ok(());
}
println!("получено {bytes_read} байт {:?}", String::from_utf8_lossy(&buffer[..bytes_read]));
self.message_count += 1;
stream.write_all(&buffer[..bytes_read]).await?;
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?;
}
}
}