Files
nocloud-core/src/main.rs
T
2026-07-17 19:25:13 +03:00

106 lines
2.6 KiB
Rust

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?;
}
}
}