commit
This commit is contained in:
parent
5d633284bf
commit
dc8a4fde98
|
@ -6,4 +6,4 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
#tokio = { version = "1", features = ["full"] }
|
byteorder = "1.4" # For byte manipulation in a cross-platform manner
|
||||||
|
|
75
src/main.rs
75
src/main.rs
|
@ -5,13 +5,13 @@ use std::net::TcpListener;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use std::process;
|
use std::process;
|
||||||
|
use byteorder::{ByteOrder, BigEndian};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
let mut port = "7890"; // default port
|
let mut port = "7890"; // default port
|
||||||
let mut log_dir = "/var/log/RMS-server"; // default log directory
|
let mut log_dir = "/var/log/RMS-server"; // default log directory
|
||||||
|
|
||||||
// Command line argument parsing
|
|
||||||
if args.len() > 1 {
|
if args.len() > 1 {
|
||||||
let mut i = 1;
|
let mut i = 1;
|
||||||
while i < args.len() {
|
while i < args.len() {
|
||||||
|
@ -19,22 +19,21 @@ fn main() {
|
||||||
"-p" | "--port" => {
|
"-p" | "--port" => {
|
||||||
if i + 1 < args.len() {
|
if i + 1 < args.len() {
|
||||||
port = &args[i + 1];
|
port = &args[i + 1];
|
||||||
i += 1;
|
i += 2;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
"-l" => {
|
"-l" => {
|
||||||
if i + 1 < args.len() {
|
if i + 1 < args.len() {
|
||||||
log_dir = &args[i + 1];
|
log_dir = &args[i + 1];
|
||||||
i += 1;
|
i += 2;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
"-h" | "--help" => {
|
"-h" | "--help" => {
|
||||||
print_usage();
|
print_usage();
|
||||||
return;
|
return;
|
||||||
}
|
},
|
||||||
_ => {}
|
_ => i += 1,
|
||||||
}
|
}
|
||||||
i += 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,50 +42,65 @@ fn main() {
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ensure the log directory exists
|
|
||||||
std::fs::create_dir_all(log_dir).expect("Failed to create log directory");
|
std::fs::create_dir_all(log_dir).expect("Failed to create log directory");
|
||||||
|
|
||||||
log_verbose(format!("Server listening on port {}", port), log_dir);
|
log_verbose(format!("Server listening on port {}", port), log_dir);
|
||||||
|
|
||||||
for stream in listener.incoming() {
|
for stream in listener.incoming() {
|
||||||
match stream {
|
match stream {
|
||||||
Ok(stream) => {
|
Ok(stream) => {
|
||||||
let peer_addr = stream.peer_addr().unwrap(); // It's safe to unwrap here as connection is already established
|
let peer_addr = stream.peer_addr().unwrap();
|
||||||
log_verbose(format!("Client connected: {}", peer_addr), log_dir);
|
log_verbose(format!("Client connected: {}", peer_addr), log_dir);
|
||||||
let log_dir = log_dir.to_string(); // Clone log_dir for the thread
|
let log_dir = log_dir.to_string();
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
handle_client(stream, &log_dir);
|
handle_client(stream, &log_dir);
|
||||||
});
|
});
|
||||||
}
|
},
|
||||||
Err(e) => {
|
Err(e) => log_verbose(format!("Connection failed: {}", e), log_dir),
|
||||||
log_verbose(format!("Connection failed: {}", e), log_dir);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function to handle a single client
|
|
||||||
fn handle_client(mut stream: std::net::TcpStream, log_dir: &str) {
|
fn handle_client(mut stream: std::net::TcpStream, log_dir: &str) {
|
||||||
let mut buffer = [0; 1024];
|
println!("Handling new client");
|
||||||
|
let mut buffer = Vec::new();
|
||||||
|
let mut data = vec![0u8; 1024];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match stream.read(&mut buffer) {
|
match stream.read(&mut data) {
|
||||||
Ok(0) => {
|
Ok(0) => {
|
||||||
break; // Client disconnected
|
println!("Client disconnected");
|
||||||
|
break;
|
||||||
},
|
},
|
||||||
Ok(size) => {
|
Ok(size) => {
|
||||||
let msg = String::from_utf8_lossy(&buffer[..size]);
|
println!("Received {} bytes", size);
|
||||||
println!("{}", msg); // Print what client sends
|
buffer.extend_from_slice(&data[..size]);
|
||||||
log_message(msg.into_owned(), log_dir); // Log to messages file
|
|
||||||
|
if buffer.len() < 5 {
|
||||||
|
continue; // Wait for enough bytes to read header
|
||||||
|
}
|
||||||
|
|
||||||
|
let msg_type = buffer[0];
|
||||||
|
let msg_len = BigEndian::read_u32(&buffer[1..5]) as usize;
|
||||||
|
|
||||||
|
if buffer.len() < 5 + msg_len {
|
||||||
|
continue; // Wait for the full message
|
||||||
|
}
|
||||||
|
|
||||||
|
let msg = String::from_utf8_lossy(&buffer[5..5+msg_len]);
|
||||||
|
println!("Type: {}, Msg: {}", msg_type, msg);
|
||||||
|
log_message(msg.to_string(), log_dir);
|
||||||
|
// Clear the buffer or handle the next message
|
||||||
|
buffer.drain(..5+msg_len);
|
||||||
},
|
},
|
||||||
Err(_) => {
|
Err(e) => {
|
||||||
break; // Connection error
|
println!("Failed to read from client: {:?}", e);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log verbose information to a file
|
|
||||||
fn log_verbose(message: String, log_dir: &str) {
|
fn log_verbose(message: String, log_dir: &str) {
|
||||||
let mut file = OpenOptions::new()
|
let mut file = OpenOptions::new()
|
||||||
.create(true)
|
.create(true)
|
||||||
|
@ -94,27 +108,22 @@ fn log_verbose(message: String, log_dir: &str) {
|
||||||
.append(true)
|
.append(true)
|
||||||
.open(Path::new(log_dir).join("verbose.log"))
|
.open(Path::new(log_dir).join("verbose.log"))
|
||||||
.expect("Failed to open verbose log file");
|
.expect("Failed to open verbose log file");
|
||||||
|
|
||||||
writeln!(file, "{}", message).expect("Failed to write to verbose log file");
|
writeln!(file, "{}", message).expect("Failed to write to verbose log file");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log raw messages to a separate file
|
|
||||||
fn log_message(message: String, log_dir: &str) {
|
fn log_message(message: String, log_dir: &str) {
|
||||||
let mut file = OpenOptions::new()
|
let mut file = OpenOptions::new()
|
||||||
.create(true)
|
.create(true)
|
||||||
.write(true)
|
.write(true)
|
||||||
.append(true)
|
.append(true)
|
||||||
.open(Path::new(log_dir).join("rawmessages.log"))
|
.open(Path::new(log_dir).join("messages.log"))
|
||||||
.expect("Failed to open message log file");
|
.expect("Failed to open message log file");
|
||||||
|
|
||||||
writeln!(file, "{}", message).expect("Failed to write to message log file");
|
writeln!(file, "{}", message).expect("Failed to write to message log file");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print usage information
|
|
||||||
fn print_usage() {
|
fn print_usage() {
|
||||||
println!("Usage: rms-server [-p/--port PORT] [-l LOG_DIR] [-h/--help]");
|
println!("Usage: rms-server [-p/--port PORT] [-l LOG_DIR] [-h/--help]");
|
||||||
println!("Options:");
|
println!("Options:");
|
||||||
println!(" -p, --port PORT Set the port number (default: 7890)");
|
println!(" -p, --port PORT Set the port number (default: 7890)");
|
||||||
println!(" -l LOG_DIR Set the log directory (default: /var/log/RMS-server)");
|
println!(" -l LOG_DIR");
|
||||||
println!(" -h, --help Print this help message");
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue