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:
parent
7a97e7e07a
commit
8cb724fe0d
@ -1,7 +1,9 @@
|
|||||||
pub mod logger;
|
pub mod logger;
|
||||||
|
mod tcp;
|
||||||
pub mod udp;
|
pub mod udp;
|
||||||
|
|
||||||
use crate::medium::logger::Logger;
|
use crate::medium::logger::Logger;
|
||||||
|
use crate::medium::tcp::{TCPClientMedium, TCPServerMedium};
|
||||||
use crate::medium::udp::UdpMedium;
|
use crate::medium::udp::UdpMedium;
|
||||||
use log::info;
|
use log::info;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
@ -12,7 +14,7 @@ pub trait ReadMedium: Read + Send {}
|
|||||||
|
|
||||||
pub trait WriteMedium: Write + 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 split(&self) -> (Box<dyn ReadMedium>, Box<dyn WriteMedium>);
|
||||||
|
|
||||||
fn name(&self) -> String;
|
fn name(&self) -> String;
|
||||||
@ -31,6 +33,12 @@ pub enum Mediums {
|
|||||||
remote_addr: SocketAddr,
|
remote_addr: SocketAddr,
|
||||||
},
|
},
|
||||||
Logger,
|
Logger,
|
||||||
|
TcpClient {
|
||||||
|
remote_addr: SocketAddr,
|
||||||
|
},
|
||||||
|
TcpServer {
|
||||||
|
local_addr: SocketAddr,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mediums {
|
impl Mediums {
|
||||||
@ -41,6 +49,8 @@ impl Mediums {
|
|||||||
remote_addr,
|
remote_addr,
|
||||||
} => Box::new(UdpMedium::new(*local_addr, *remote_addr)),
|
} => Box::new(UdpMedium::new(*local_addr, *remote_addr)),
|
||||||
Mediums::Logger => Box::new(Logger),
|
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
125
src/medium/tcp.rs
Normal 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 {}
|
Loading…
x
Reference in New Issue
Block a user