From bd923afe53de552c1f69e0db5a4490c73a294b91 Mon Sep 17 00:00:00 2001 From: 魏曹先生 <1992414357@qq.com> Date: Sun, 14 Sep 2025 22:42:08 +0800 Subject: Add TcpServerConfigs --- .../utils/tcp_connection/src/target_configure.rs | 51 ++++++++++++++++++ .../utils/tcp_connection/src/target_connection.rs | 63 ++++++++++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 crates/utils/tcp_connection/src/target_configure.rs create mode 100644 crates/utils/tcp_connection/src/target_connection.rs (limited to 'crates/utils/tcp_connection/src') diff --git a/crates/utils/tcp_connection/src/target_configure.rs b/crates/utils/tcp_connection/src/target_configure.rs new file mode 100644 index 0000000..09c4d0d --- /dev/null +++ b/crates/utils/tcp_connection/src/target_configure.rs @@ -0,0 +1,51 @@ +#[derive(Default, Debug, Clone, Copy)] +pub struct ServerTargetConfig { + /// Only process a single connection, then shut down the server. + once: bool, + + /// Timeout duration in milliseconds. (0 is Closed) + timeout: u64, +} + +impl ServerTargetConfig { + /// Set `once` to True + /// This method configures the `once` field of `ServerTargetConfig`. + pub fn once(mut self) -> Self { + self.once = true; + self + } + + /// Set `timeout` to the given value + /// This method configures the `timeout` field of `ServerTargetConfig`. + pub fn timeout(mut self, timeout: u64) -> Self { + self.timeout = timeout; + self + } + + /// Set `once` to the given value + /// This method configures the `once` field of `ServerTargetConfig`. + pub fn set_once(&mut self, enable: bool) { + self.once = enable; + } + + /// Set `timeout` to the given value + /// This method configures the `timeout` field of `ServerTargetConfig`. + pub fn set_timeout(&mut self, timeout: u64) { + self.timeout = timeout; + } + + /// Check if the server is configured to process only a single connection. + /// Returns `true` if the server will shut down after processing one connection. + pub fn is_once(&self) -> bool { + self.once + } + + /// Get the current timeout value in milliseconds. + /// Returns the timeout duration. A value of 0 indicates the connection is closed. + pub fn get_timeout(&self) -> u64 { + self.timeout + } +} + +#[derive(Default, Debug, Clone, Copy)] +pub struct ClientTargetConfig {} diff --git a/crates/utils/tcp_connection/src/target_connection.rs b/crates/utils/tcp_connection/src/target_connection.rs new file mode 100644 index 0000000..1e25edd --- /dev/null +++ b/crates/utils/tcp_connection/src/target_connection.rs @@ -0,0 +1,63 @@ +use tokio::{net::TcpListener, spawn}; + +use crate::{ + error::TcpTargetError, + handle::{ClientHandle, ServerHandle}, + instance::ConnectionInstance, + target::TcpServerTarget, + target_configure::ServerTargetConfig, +}; + +impl TcpServerTarget +where + Client: ClientHandle, + Server: ServerHandle, +{ + pub async fn connect(&self) -> Result<(), TcpTargetError> { + Ok(()) + } + + pub async fn listen(&self) -> Result<(), TcpTargetError> { + let addr = self.get_addr(); + let listener = match TcpListener::bind(addr.clone()).await { + Ok(listener) => listener, + Err(_) => { + let err = format!("Bind to `{}` failed", addr); + return Err(TcpTargetError::from(err)); + } + }; + + let cfg: ServerTargetConfig = match self.get_server_cfg() { + Some(cfg) => cfg.clone(), + None => ServerTargetConfig::default(), + }; + + if cfg.is_once() { + let (stream, _) = match listener.accept().await { + Ok(result) => result, + Err(e) => { + let err = format!("Accept connection failed: {}", e); + return Err(TcpTargetError::from(err)); + } + }; + let instance = ConnectionInstance::from(stream); + Server::process(instance).await; + } else { + loop { + let (stream, _) = match listener.accept().await { + Ok(result) => result, + Err(e) => { + let err = format!("Accept connection failed: {}", e); + return Err(TcpTargetError::from(err)); + } + }; + let instance = ConnectionInstance::from(stream); + spawn(async move { + Server::process(instance).await; + }); + } + } + + Ok(()) + } +} -- cgit