2025-07-13 08:05:56 +08:00
|
|
|
use tokio::io::{self, ErrorKind, Interest};
|
2025-07-11 23:03:21 +08:00
|
|
|
use tokio::net::{TcpListener, TcpStream};
|
2025-07-13 08:05:56 +08:00
|
|
|
use tokio::time::{self, Duration};
|
2025-07-10 18:27:09 +08:00
|
|
|
|
|
|
|
pub(crate) struct TcpServer;
|
|
|
|
|
|
|
|
impl TcpServer {
|
|
|
|
pub(crate) async fn init() {
|
|
|
|
match TcpListener::bind("127.0.0.1:12345").await {
|
|
|
|
Ok(listener) => loop {
|
|
|
|
match listener.accept().await {
|
|
|
|
Ok((socket, addr)) => {
|
|
|
|
log::info!("New client connected: {addr}");
|
|
|
|
|
2025-07-13 08:05:56 +08:00
|
|
|
tokio::spawn(async move {
|
|
|
|
let mut retry_times = 0;
|
|
|
|
|
|
|
|
while retry_times <= 3 {
|
|
|
|
let result = Self::process(&socket).await;
|
|
|
|
|
|
|
|
match result {
|
|
|
|
Ok(_) => continue,
|
|
|
|
Err(e) if e.kind() == ErrorKind::WouldBlock => continue,
|
|
|
|
Err(e) => {
|
|
|
|
if retry_times == 3 {
|
|
|
|
log::error!("Failed to process this socket: {e}");
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
retry_times += 1;
|
|
|
|
|
|
|
|
log::error!(
|
|
|
|
"Failed to process this socket: {e}. Retry {retry_times} time(s)..."
|
|
|
|
);
|
|
|
|
|
|
|
|
time::sleep(Duration::from_secs(1)).await;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2025-07-10 18:27:09 +08:00
|
|
|
}
|
|
|
|
Err(e) => log::error!("Couldn't get client: {e:?}"),
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Err(e) => log::error!("Failed to bind port: {e:?}"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-07-13 08:05:56 +08:00
|
|
|
async fn process(socket: &TcpStream) -> io::Result<()> {
|
|
|
|
let ready = socket
|
|
|
|
.ready(Interest::READABLE | Interest::WRITABLE)
|
|
|
|
.await?;
|
|
|
|
if ready.is_readable() {
|
|
|
|
// Size of per received data shound be smaller than 1KiB.
|
|
|
|
let mut buffer = [0; 1024];
|
|
|
|
let size = socket.try_read(&mut buffer)?;
|
2025-07-12 12:48:34 +08:00
|
|
|
|
2025-07-13 08:05:56 +08:00
|
|
|
log::info!("Received {size} Bytes message.")
|
|
|
|
|
|
|
|
// TODO: Start dispatching messages here.
|
|
|
|
}
|
|
|
|
if ready.is_writable() {
|
|
|
|
// TODO: Start sending back message here.
|
|
|
|
let size = socket.try_write(b"Hello from server written in Rust!")?;
|
|
|
|
|
|
|
|
log::info!("Sent {size} Bytes message.")
|
2025-07-12 12:48:34 +08:00
|
|
|
}
|
2025-07-13 08:05:56 +08:00
|
|
|
|
|
|
|
Ok(())
|
2025-07-10 18:27:09 +08:00
|
|
|
}
|
|
|
|
}
|