Overall improvements
This commit is contained in:
parent
6df9155c32
commit
9096e94f00
5 changed files with 85 additions and 85 deletions
|
|
@ -32,10 +32,7 @@ pub struct Config {
|
||||||
impl Config {
|
impl Config {
|
||||||
/// Creates a new configuration by parsing the supplied arguments. It is
|
/// Creates a new configuration by parsing the supplied arguments. It is
|
||||||
/// intended for use with [`env::args()`].
|
/// intended for use with [`env::args()`].
|
||||||
pub fn new<T>(mut args: T) -> Result<Config, Box<dyn Error>>
|
pub fn new<T: Iterator<Item = String>>(mut args: T) -> Result<Config, Box<dyn Error>> {
|
||||||
where
|
|
||||||
T: Iterator<Item = String>,
|
|
||||||
{
|
|
||||||
let mut config = Config {
|
let mut config = Config {
|
||||||
ip_address: Ipv4Addr::new(127, 0, 0, 1),
|
ip_address: Ipv4Addr::new(127, 0, 0, 1),
|
||||||
port: 69,
|
port: 69,
|
||||||
|
|
|
||||||
|
|
@ -121,15 +121,22 @@ impl Server {
|
||||||
ErrorCode::FileExists => {
|
ErrorCode::FileExists => {
|
||||||
let worker_options =
|
let worker_options =
|
||||||
parse_options(options, RequestType::Read(file_path.metadata()?.len()))?;
|
parse_options(options, RequestType::Read(file_path.metadata()?.len()))?;
|
||||||
|
let mut socket: Box<dyn Socket>;
|
||||||
|
|
||||||
if self.single_port {
|
if self.single_port {
|
||||||
let mut socket = create_single_socket(&self.socket, to)?;
|
let single_socket = create_single_socket(&self.socket, to)?;
|
||||||
|
self.clients.insert(*to, single_socket.sender());
|
||||||
|
self.largest_block_size =
|
||||||
|
max(self.largest_block_size, worker_options.block_size);
|
||||||
|
|
||||||
|
socket = Box::new(single_socket);
|
||||||
|
} else {
|
||||||
|
socket = Box::new(create_multi_socket(&self.socket.local_addr()?, to)?);
|
||||||
|
}
|
||||||
|
|
||||||
socket.set_read_timeout(worker_options.timeout)?;
|
socket.set_read_timeout(worker_options.timeout)?;
|
||||||
socket.set_write_timeout(worker_options.timeout)?;
|
socket.set_write_timeout(worker_options.timeout)?;
|
||||||
|
|
||||||
self.clients.insert(*to, socket.sender());
|
|
||||||
self.largest_block_size =
|
|
||||||
max(self.largest_block_size, worker_options.block_size);
|
|
||||||
accept_request(
|
accept_request(
|
||||||
&socket,
|
&socket,
|
||||||
options,
|
options,
|
||||||
|
|
@ -144,26 +151,6 @@ impl Server {
|
||||||
worker_options.window_size,
|
worker_options.window_size,
|
||||||
);
|
);
|
||||||
worker.send()
|
worker.send()
|
||||||
} else {
|
|
||||||
let socket = create_multi_socket(&self.socket.local_addr()?, to)?;
|
|
||||||
socket.set_read_timeout(Some(worker_options.timeout))?;
|
|
||||||
socket.set_write_timeout(Some(worker_options.timeout))?;
|
|
||||||
|
|
||||||
accept_request(
|
|
||||||
&socket,
|
|
||||||
options,
|
|
||||||
RequestType::Read(file_path.metadata()?.len()),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let worker = Worker::new(
|
|
||||||
socket,
|
|
||||||
file_path.clone(),
|
|
||||||
worker_options.block_size,
|
|
||||||
worker_options.timeout,
|
|
||||||
worker_options.window_size,
|
|
||||||
);
|
|
||||||
worker.send()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => Err("Unexpected error code when checking file".into()),
|
_ => Err("Unexpected error code when checking file".into()),
|
||||||
}
|
}
|
||||||
|
|
@ -191,15 +178,22 @@ impl Server {
|
||||||
),
|
),
|
||||||
ErrorCode::FileNotFound => {
|
ErrorCode::FileNotFound => {
|
||||||
let worker_options = parse_options(options, RequestType::Write)?;
|
let worker_options = parse_options(options, RequestType::Write)?;
|
||||||
|
let mut socket: Box<dyn Socket>;
|
||||||
|
|
||||||
if self.single_port {
|
if self.single_port {
|
||||||
let mut socket = create_single_socket(&self.socket, to)?;
|
let single_socket = create_single_socket(&self.socket, to)?;
|
||||||
|
self.clients.insert(*to, single_socket.sender());
|
||||||
|
self.largest_block_size =
|
||||||
|
max(self.largest_block_size, worker_options.block_size);
|
||||||
|
|
||||||
|
socket = Box::new(single_socket);
|
||||||
|
} else {
|
||||||
|
socket = Box::new(create_multi_socket(&self.socket.local_addr()?, to)?);
|
||||||
|
}
|
||||||
|
|
||||||
socket.set_read_timeout(worker_options.timeout)?;
|
socket.set_read_timeout(worker_options.timeout)?;
|
||||||
socket.set_write_timeout(worker_options.timeout)?;
|
socket.set_write_timeout(worker_options.timeout)?;
|
||||||
|
|
||||||
self.clients.insert(*to, socket.sender());
|
|
||||||
self.largest_block_size =
|
|
||||||
max(self.largest_block_size, worker_options.block_size);
|
|
||||||
accept_request(&socket, options, RequestType::Write)?;
|
accept_request(&socket, options, RequestType::Write)?;
|
||||||
|
|
||||||
let worker = Worker::new(
|
let worker = Worker::new(
|
||||||
|
|
@ -210,22 +204,6 @@ impl Server {
|
||||||
worker_options.window_size,
|
worker_options.window_size,
|
||||||
);
|
);
|
||||||
worker.receive()
|
worker.receive()
|
||||||
} else {
|
|
||||||
let socket = create_multi_socket(&self.socket.local_addr()?, to)?;
|
|
||||||
socket.set_read_timeout(Some(worker_options.timeout))?;
|
|
||||||
socket.set_write_timeout(Some(worker_options.timeout))?;
|
|
||||||
|
|
||||||
accept_request(&socket, options, RequestType::Write)?;
|
|
||||||
|
|
||||||
let worker = Worker::new(
|
|
||||||
socket,
|
|
||||||
file_path.clone(),
|
|
||||||
worker_options.block_size,
|
|
||||||
worker_options.timeout,
|
|
||||||
worker_options.window_size,
|
|
||||||
);
|
|
||||||
worker.receive()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => Err("Unexpected error code when checking file".into()),
|
_ => Err("Unexpected error code when checking file".into()),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,8 @@ use crate::Packet;
|
||||||
|
|
||||||
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5);
|
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(5);
|
||||||
|
|
||||||
/// Socket `trait` is used for easy message transmission of common TFTP
|
/// Socket `trait` is used to allow building custom sockets to be used for
|
||||||
/// message types. This `trait` is implemented for [`UdpSocket`] and used
|
/// TFTP communication.
|
||||||
/// for abstraction of single socket communication.
|
|
||||||
pub trait Socket: Send + Sync + 'static {
|
pub trait Socket: Send + Sync + 'static {
|
||||||
/// Sends a [`Packet`] to the socket's connected remote [`Socket`].
|
/// Sends a [`Packet`] to the socket's connected remote [`Socket`].
|
||||||
fn send(&self, packet: &Packet) -> Result<(), Box<dyn Error>>;
|
fn send(&self, packet: &Packet) -> Result<(), Box<dyn Error>>;
|
||||||
|
|
@ -165,6 +164,36 @@ impl ServerSocket {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Socket + ?Sized> Socket for Box<T> {
|
||||||
|
fn send(&self, packet: &Packet) -> Result<(), Box<dyn Error>> {
|
||||||
|
(**self).send(packet)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn send_to(&self, packet: &Packet, to: &SocketAddr) -> Result<(), Box<dyn Error>> {
|
||||||
|
(**self).send_to(packet, to)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recv(&self, buf: &mut [u8]) -> Result<Packet, Box<dyn Error>> {
|
||||||
|
(**self).recv(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recv_from(&self, buf: &mut [u8]) -> Result<(Packet, SocketAddr), Box<dyn Error>> {
|
||||||
|
(**self).recv_from(buf)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remote_addr(&self) -> Result<SocketAddr, Box<dyn Error>> {
|
||||||
|
(**self).remote_addr()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_read_timeout(&mut self, dur: Duration) -> Result<(), Box<dyn Error>> {
|
||||||
|
(**self).set_read_timeout(dur)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_write_timeout(&mut self, dur: Duration) -> Result<(), Box<dyn Error>> {
|
||||||
|
(**self).set_write_timeout(dur)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ use std::{
|
||||||
io::{Read, Write},
|
io::{Read, Write},
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Window `struct` is used to store chunks of data from a file.
|
/// Window `struct` is used to store chunks of data from a file. It is
|
||||||
/// It is used to store the data that is being sent or received for
|
/// used to help store the data that is being sent or received for the
|
||||||
/// Windowsize option.
|
/// [RFC 7440](https://www.rfc-editor.org/rfc/rfc7440) Windowsize option.
|
||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```rust
|
/// ```rust
|
||||||
|
|
@ -206,8 +206,10 @@ mod tests {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_must_use)]
|
||||||
fn clean(file_name: &str) {
|
fn clean(file_name: &str) {
|
||||||
let file_name = DIR_NAME.to_string() + "/" + file_name;
|
let file_name = DIR_NAME.to_string() + "/" + file_name;
|
||||||
fs::remove_file(file_name).unwrap();
|
fs::remove_file(file_name).unwrap();
|
||||||
|
fs::remove_dir(DIR_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ const TIMEOUT_BUFFER: Duration = Duration::from_secs(1);
|
||||||
/// socket.connect(SocketAddr::from_str("127.0.0.1:12345").unwrap()).unwrap();
|
/// socket.connect(SocketAddr::from_str("127.0.0.1:12345").unwrap()).unwrap();
|
||||||
///
|
///
|
||||||
/// let worker = Worker::new(
|
/// let worker = Worker::new(
|
||||||
/// socket,
|
/// Box::new(socket),
|
||||||
/// PathBuf::from_str("Cargo.toml").unwrap(),
|
/// PathBuf::from_str("Cargo.toml").unwrap(),
|
||||||
/// 512,
|
/// 512,
|
||||||
/// Duration::from_secs(1),
|
/// Duration::from_secs(1),
|
||||||
|
|
@ -37,24 +37,18 @@ const TIMEOUT_BUFFER: Duration = Duration::from_secs(1);
|
||||||
///
|
///
|
||||||
/// worker.send().unwrap();
|
/// worker.send().unwrap();
|
||||||
/// ```
|
/// ```
|
||||||
pub struct Worker<T>
|
pub struct Worker<T: Socket + ?Sized> {
|
||||||
where
|
socket: Box<T>,
|
||||||
T: Socket,
|
|
||||||
{
|
|
||||||
socket: T,
|
|
||||||
file_name: PathBuf,
|
file_name: PathBuf,
|
||||||
blk_size: usize,
|
blk_size: usize,
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
windowsize: u16,
|
windowsize: u16,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Worker<T>
|
impl<T: Socket + ?Sized> Worker<T> {
|
||||||
where
|
|
||||||
T: Socket,
|
|
||||||
{
|
|
||||||
/// Creates a new [`Worker`] with the supplied options.
|
/// Creates a new [`Worker`] with the supplied options.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
socket: T,
|
socket: Box<T>,
|
||||||
file_name: PathBuf,
|
file_name: PathBuf,
|
||||||
blk_size: usize,
|
blk_size: usize,
|
||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue