add data transfer speed printing

This commit is contained in:
Daniella / Tove 2023-10-03 02:16:02 +02:00
parent 9a2d4c2931
commit 289b2ef7a0
Signed by: TudbuT
GPG key ID: 7D63D5634B7C417F
4 changed files with 86 additions and 41 deletions

View file

@ -4,6 +4,9 @@
This tool bypasses port restrictions of your router using some not-very-powerful This tool bypasses port restrictions of your router using some not-very-powerful
server (a cheap 1€ vserver will suffice.) server (a cheap 1€ vserver will suffice.)
NEW: Modem support! RevPFW3 can now interact with modems using AT commands. A demo
is included for the SIM800L GSM modem.
--- ---
### How to download it ### How to download it

View file

@ -67,9 +67,12 @@ fn connect(params: &ClientParams) -> Connection {
} }
} }
serial.set_timeout(Duration::from_millis(600000)).unwrap(); serial.set_timeout(Duration::from_millis(600000)).unwrap();
return Connection::new_serial(serial); return Connection::new_serial(serial, true);
} }
Connection::new_tcp(TcpStream::connect((params.server_ip, params.server_port)).unwrap()) Connection::new_tcp(
TcpStream::connect((params.server_ip, params.server_port)).unwrap(),
true,
)
} }
pub fn client(params: ClientParams) { pub fn client(params: ClientParams) {
@ -94,6 +97,7 @@ pub fn client(params: ClientParams) {
tcp.write_all(&[PacketType::KeepAlive.ordinal() as u8]) tcp.write_all(&[PacketType::KeepAlive.ordinal() as u8])
.unwrap(); .unwrap();
println!();
println!("READY!"); println!("READY!");
let mut tcp = SocketAdapter::new(tcp); let mut tcp = SocketAdapter::new(tcp);
@ -163,6 +167,7 @@ pub fn client(params: ClientParams) {
PacketType::NewClient => { PacketType::NewClient => {
let mut tcp = SocketAdapter::new(Connection::new_tcp( let mut tcp = SocketAdapter::new(Connection::new_tcp(
TcpStream::connect((params.dest_ip, params.dest_port)).unwrap(), TcpStream::connect((params.dest_ip, params.dest_port)).unwrap(),
false,
)); ));
tcp.set_nonblocking(true); tcp.set_nonblocking(true);
sockets.insert((id, id += 1).0, tcp); sockets.insert((id, id += 1).0, tcp);

View file

@ -42,7 +42,7 @@ pub fn server(port: u16, key: &str, sleep_delay_ms: u64) {
tcpl.set_nonblocking(true).unwrap(); tcpl.set_nonblocking(true).unwrap();
let mut tcp = SocketAdapter::new(Connection::new_tcp(tcp)); let mut tcp = SocketAdapter::new(Connection::new_tcp(tcp, false));
tcp.set_nonblocking(true); tcp.set_nonblocking(true);
let mut sockets: HashMap<u64, SocketAdapter> = HashMap::new(); let mut sockets: HashMap<u64, SocketAdapter> = HashMap::new();
let mut id = 0; let mut id = 0;
@ -60,7 +60,7 @@ pub fn server(port: u16, key: &str, sleep_delay_ms: u64) {
} }
if let Ok(new) = tcpl.accept() { if let Ok(new) = tcpl.accept() {
let mut new = SocketAdapter::new(Connection::new_tcp(new.0)); let mut new = SocketAdapter::new(Connection::new_tcp(new.0, false));
new.set_nonblocking(true); new.set_nonblocking(true);
sockets.insert((id, id += 1).0, new); sockets.insert((id, id += 1).0, new);
tcp.write(&[PacketType::NewClient.ordinal() as u8]).unwrap(); tcp.write(&[PacketType::NewClient.ordinal() as u8]).unwrap();

View file

@ -1,8 +1,8 @@
use std::{ use std::{
io::{self, ErrorKind, Read, Write}, io::{self, stdout, ErrorKind, Read, Write},
net::{Shutdown, TcpStream}, net::{Shutdown, TcpStream},
ptr::NonNull, ptr::NonNull,
time::Duration, time::{Duration, SystemTime},
}; };
use serial::SerialPort; use serial::SerialPort;
@ -10,6 +10,15 @@ use serial::SerialPort;
trait ReadWrite: Write + Read + 'static {} trait ReadWrite: Write + Read + 'static {}
impl<T> ReadWrite for T where T: Write + Read + 'static {} impl<T> ReadWrite for T where T: Write + Read + 'static {}
enum PrintStatus {
No,
Yes {
last_print: SystemTime,
bytes: u128,
last_bytes: u128,
},
}
pub struct Connection { pub struct Connection {
readwrite: Box<dyn ReadWrite>, readwrite: Box<dyn ReadWrite>,
data: NonNull<()>, data: NonNull<()>,
@ -17,30 +26,13 @@ pub struct Connection {
close_thunk: fn(NonNull<()>) -> io::Result<()>, close_thunk: fn(NonNull<()>) -> io::Result<()>,
is_nb: bool, is_nb: bool,
is_serial: bool, is_serial: bool,
print_status: PrintStatus,
} }
impl Write for Connection { impl Write for Connection {
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
self.as_write().write_vectored(bufs)
}
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.as_write().write_all(buf)
}
fn write_fmt(&mut self, fmt: std::fmt::Arguments<'_>) -> io::Result<()> {
self.as_write().write_fmt(fmt)
}
fn by_ref(&mut self) -> &mut Self
where
Self: Sized,
{
self
}
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.as_write().write(buf) let result = self.as_write().write(buf);
self.print_status_result(result)
} }
fn flush(&mut self) -> io::Result<()> { fn flush(&mut self) -> io::Result<()> {
@ -50,19 +42,8 @@ impl Write for Connection {
impl Read for Connection { impl Read for Connection {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.as_read().read(buf) let result = self.as_read().read(buf);
} self.print_status_result(result)
fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
self.as_read().read_vectored(bufs)
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.as_read().read_to_end(buf)
}
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
self.as_read().read_to_string(buf)
} }
fn read_exact(&mut self, mut buf: &mut [u8]) -> io::Result<()> { fn read_exact(&mut self, mut buf: &mut [u8]) -> io::Result<()> {
@ -92,7 +73,7 @@ impl Read for Connection {
} }
impl Connection { impl Connection {
pub fn new_tcp(stream: TcpStream) -> Self { pub fn new_tcp(stream: TcpStream, print: bool) -> Self {
let mut stream = Box::new(stream); let mut stream = Box::new(stream);
Connection { Connection {
data: NonNull::from(stream.as_mut()).cast(), data: NonNull::from(stream.as_mut()).cast(),
@ -105,9 +86,18 @@ impl Connection {
}, },
is_nb: false, is_nb: false,
is_serial: false, is_serial: false,
print_status: if print {
PrintStatus::Yes {
last_print: SystemTime::now(),
bytes: 0,
last_bytes: 0,
}
} else {
PrintStatus::No
},
} }
} }
pub fn new_serial<T: SerialPort + 'static>(serial: T) -> Self { pub fn new_serial<T: SerialPort + 'static>(serial: T, print: bool) -> Self {
let mut serial = Box::new(serial); let mut serial = Box::new(serial);
Connection { Connection {
data: NonNull::from(serial.as_mut()).cast(), data: NonNull::from(serial.as_mut()).cast(),
@ -124,6 +114,15 @@ impl Connection {
close_thunk: |_data| Ok(()), close_thunk: |_data| Ok(()),
is_nb: false, is_nb: false,
is_serial: true, is_serial: true,
print_status: if print {
PrintStatus::Yes {
last_print: SystemTime::now(),
bytes: 0,
last_bytes: 0,
}
} else {
PrintStatus::No
},
} }
} }
fn as_read(&mut self) -> &mut (dyn Read) { fn as_read(&mut self) -> &mut (dyn Read) {
@ -132,6 +131,7 @@ impl Connection {
fn as_write(&mut self) -> &mut (dyn Write) { fn as_write(&mut self) -> &mut (dyn Write) {
&mut self.readwrite &mut self.readwrite
} }
#[allow(dead_code)]
pub fn is_nonblocking(&self) -> bool { pub fn is_nonblocking(&self) -> bool {
self.is_nb self.is_nb
} }
@ -146,4 +146,41 @@ impl Connection {
pub fn is_serial(&self) -> bool { pub fn is_serial(&self) -> bool {
self.is_serial self.is_serial
} }
fn print_status(&mut self, add: usize) {
if let &mut PrintStatus::Yes {
ref mut last_print,
ref mut bytes,
ref mut last_bytes,
} = &mut self.print_status
{
*bytes += add as u128;
if last_print.elapsed().unwrap().as_secs() > 0 {
let diff = *bytes - *last_bytes;
let bps = to_units(diff);
let total = to_units(*bytes);
print!("\r\x1b[KCurrent transfer speed: {bps}B/s, transferred {total}B so far.");
stdout().flush().unwrap();
*last_bytes = *bytes;
*last_print = SystemTime::now();
}
}
}
fn print_status_result(&mut self, result: io::Result<usize>) -> io::Result<usize> {
if let Ok(b) = result {
self.print_status(b)
}
result
}
}
fn to_units(diff: u128) -> String {
match diff {
x @ 1_000_000_000_000.. => ((x / 1_000_000_000) as f64 / 1000.0).to_string() + "G",
x @ 1_000_000_000.. => ((x / 1_000_000) as f64 / 1000.0).to_string() + "G",
x @ 1_000_000.. => ((x / 1_000) as f64 / 1000.0).to_string() + "M",
x @ 10_000.. => (x as f64 / 1000.0).to_string() + "K",
x => x.to_string(),
}
} }