Sebastian Hugentobler
dac95b7dae
During that process, many shortcomings with the socket server and the bank lib were fixed. I am aware a massive commit like this is not ideal.
65 lines
1.4 KiB
Rust
65 lines
1.4 KiB
Rust
use std::io::{Read, Write};
|
|
use std::net::{TcpListener, TcpStream};
|
|
use std::sync::{Arc, RwLock};
|
|
|
|
use anyhow::{bail, Result};
|
|
|
|
use bank::bank::Bank;
|
|
|
|
use crate::commands::Commands;
|
|
use crate::protocol;
|
|
use crate::threadpool::ThreadPool;
|
|
|
|
pub fn run(host: &str, threads: usize) -> Result<()> {
|
|
let listener = TcpListener::bind(host)?;
|
|
let pool = ThreadPool::new(threads);
|
|
let cmds = Arc::new(Commands::new());
|
|
|
|
let bank = Arc::new(RwLock::new(Bank::new()));
|
|
|
|
for stream in listener.incoming() {
|
|
let cmds = cmds.clone();
|
|
let bank = bank.clone();
|
|
|
|
let stream = stream?;
|
|
|
|
pool.execute(move || {
|
|
if let Err(e) = handle_connection(bank, &cmds, stream) {
|
|
error!("{}", e);
|
|
}
|
|
});
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn handle_connection(
|
|
bank: Arc<RwLock<Bank>>,
|
|
cmds: &Commands,
|
|
mut stream: TcpStream,
|
|
) -> Result<()> {
|
|
const BUF_SIZE: usize = 64;
|
|
|
|
let mut data: Vec<u8> = vec![];
|
|
let mut buffer = [0; BUF_SIZE];
|
|
|
|
let mut read = stream.read(&mut buffer)?;
|
|
while read > 0 {
|
|
data.append(&mut buffer[..read].to_vec());
|
|
read = stream.read(&mut buffer)?;
|
|
}
|
|
|
|
if data[..2] != protocol::START {
|
|
bail!("got {:?} as first bytes, not my problem", &data[..2]);
|
|
}
|
|
|
|
let cmd: u8 = (data[2] & 0b1111_0000) >> 4;
|
|
trace!("got command {}", cmd);
|
|
|
|
cmds.run(bank, cmd, &data[3..], &stream)?;
|
|
|
|
stream.flush()?;
|
|
|
|
Ok(())
|
|
}
|