Added the TCP medium

+ Split impl for Server/Clients
+ Working, but slow I think it's time to look at performance
This commit is contained in:
Joey Hines 2025-03-30 13:46:51 -06:00
parent 7a97e7e07a
commit 8cb724fe0d
Signed by: joeyahines
GPG Key ID: 38BA6F25C94C9382
3 changed files with 137 additions and 2 deletions

View File

@ -11,4 +11,4 @@ pretty-hex = "0.4.1"
env_logger = "0.11.6"
clap = { version = "4.5.34", features = ["derive"] }
config = "0.15.11"
serde = { version = "1.0.219", features = ["derive"] }
serde = { version = "1.0.219", features = ["derive"] }

View File

@ -1,7 +1,9 @@
pub mod logger;
mod tcp;
pub mod udp;
use crate::medium::logger::Logger;
use crate::medium::tcp::{TCPClientMedium, TCPServerMedium};
use crate::medium::udp::UdpMedium;
use log::info;
use serde::Deserialize;
@ -12,7 +14,7 @@ pub trait ReadMedium: Read + Send {}
pub trait WriteMedium: Write + Send {}
pub trait Medium: Read + Write + Send {
pub trait Medium: Send {
fn split(&self) -> (Box<dyn ReadMedium>, Box<dyn WriteMedium>);
fn name(&self) -> String;
@ -31,6 +33,12 @@ pub enum Mediums {
remote_addr: SocketAddr,
},
Logger,
TcpClient {
remote_addr: SocketAddr,
},
TcpServer {
local_addr: SocketAddr,
},
}
impl Mediums {
@ -41,6 +49,8 @@ impl Mediums {
remote_addr,
} => Box::new(UdpMedium::new(*local_addr, *remote_addr)),
Mediums::Logger => Box::new(Logger),
Mediums::TcpClient { remote_addr } => Box::new(TCPClientMedium::new(*remote_addr)),
Mediums::TcpServer { local_addr } => Box::new(TCPServerMedium::new(*local_addr)),
}
}
}

125
src/medium/tcp.rs Normal file
View File

@ -0,0 +1,125 @@
use crate::medium::{Medium, ReadMedium, WriteMedium};
use log::info;
use std::fmt::{Display, Formatter};
use std::io::{Error, ErrorKind};
use std::net::{SocketAddr, TcpListener, TcpStream};
pub enum TCPType {
Client,
Server,
}
impl Display for TCPType {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let type_name = match self {
TCPType::Client => "Client",
TCPType::Server => "Server",
};
write!(f, "{}", type_name)
}
}
pub trait TCPMedium: Send {
fn medium_type() -> TCPType;
fn handle_init(&mut self) -> Result<(), std::io::Error>;
fn tcp_stream(&self) -> Result<&TcpStream, std::io::Error>;
}
impl<T: TCPMedium> Medium for T {
fn split(&self) -> (Box<dyn ReadMedium>, Box<dyn WriteMedium>) {
let read_stream = self.tcp_stream().unwrap().try_clone().unwrap();
let write_stream = self.tcp_stream().unwrap().try_clone().unwrap();
(Box::new(read_stream), Box::new(write_stream))
}
fn name(&self) -> String {
format!("TCP {}", Self::medium_type())
}
fn init(&mut self) -> Result<(), Error> {
self.handle_init()
}
}
pub struct TCPClientMedium {
dest_addr: SocketAddr,
tcp_stream: Option<TcpStream>,
}
impl TCPClientMedium {
pub fn new(dest_addr: SocketAddr) -> Self {
Self {
dest_addr,
tcp_stream: None,
}
}
}
impl TCPMedium for TCPClientMedium {
fn medium_type() -> TCPType {
TCPType::Client
}
fn handle_init(&mut self) -> Result<(), Error> {
info!("Connecting to TCP server at {}...", self.dest_addr);
self.tcp_stream = Some(TcpStream::connect(self.dest_addr)?);
info!("Connected to TCP server.");
Ok(())
}
fn tcp_stream(&self) -> Result<&TcpStream, Error> {
self.tcp_stream
.as_ref()
.ok_or(Error::from(ErrorKind::NotConnected))
}
}
pub struct TCPServerMedium {
server_addr: SocketAddr,
tcp_stream: Option<TcpStream>,
}
impl TCPServerMedium {
pub fn new(server_addr: SocketAddr) -> Self {
Self {
server_addr,
tcp_stream: None,
}
}
}
impl TCPMedium for TCPServerMedium {
fn medium_type() -> TCPType {
TCPType::Server
}
fn handle_init(&mut self) -> Result<(), Error> {
info!(
"Waiting for connections to TCP server @ {}...",
self.server_addr
);
let listener = TcpListener::bind(self.server_addr)?;
let (stream, addr) = listener.accept()?;
info!("Got connection from {}", addr);
self.tcp_stream = Some(stream);
Ok(())
}
fn tcp_stream(&self) -> Result<&TcpStream, Error> {
self.tcp_stream
.as_ref()
.ok_or(Error::from(ErrorKind::NotConnected))
}
}
impl ReadMedium for TcpStream {}
impl WriteMedium for TcpStream {}