use std::io::BufRead; use std::io::BufReader; use std::io::Read; use std::io::Write; use std::net::TcpStream; use std::str; use std::sync::Arc; use std::sync::Mutex; use std::thread; use std::time::Duration; const SERVER_PORT: u16 = 31026; const MAX_MESSAGE_LENGTH: usize = 200; const MAX_USER_INPUT: usize = 198; const READING_INTERVAL: u64 = 2; type Err = Box<dyn std::error::Error + Send + Sync + 'static>; type Result<T> = std::result::Result<T, Err>; struct Client { stream: BufReader<TcpStream>, read_buf: Vec<u8>, } impl Client { fn connect_to_server() -> Result<Self> { let stream = TcpStream::connect(("127.0.0.1", SERVER_PORT))?; Ok(Self { stream: BufReader::new(stream), read_buf: Vec::with_capacity(MAX_MESSAGE_LENGTH), }) } fn handshake(&mut self) -> Result<()> { const SERVER_MESSAGE: &str = "Hello, I'm the server"; write!(self.stream.get_mut(), "Hello, I'm the client")?; let read = (&mut self.stream) .take(MAX_MESSAGE_LENGTH as u64) .read_until(0, &mut self.read_buf)?; let server_message = str::from_utf8(&self.read_buf[..read - 1])?.trim(); println!("{}", server_message); assert_eq!(server_message, SERVER_MESSAGE); self.read_buf.clear(); Ok(()) } fn get_request(&mut self) -> Result<()> { write!(self.stream.get_mut(), "g:")?; let read = (&mut self.stream) .take(MAX_MESSAGE_LENGTH as u64) .read_until(0, &mut self.read_buf)?; let server_message = str::from_utf8(&self.read_buf[..read - 1])?.trim(); println!("get: {}", server_message); self.read_buf.clear(); Ok(()) } fn set_request(&mut self, message: &str) -> Result<()> { // write!(self.stream.get_mut(), "s:{}", message)?; //does not work, server issue? self.stream .get_mut() .write_all(format!("s:{}", message).as_bytes())?; let read = (&mut self.stream) .take(MAX_MESSAGE_LENGTH as u64) .read_until(0, &mut self.read_buf)?; let server_message = str::from_utf8(&self.read_buf[..read - 1])?.trim(); println!("set: {}", server_message); self.read_buf.clear(); Ok(()) } } fn start_reader_thread(client: Arc<Mutex<Client>>) { thread::spawn(move || read_continously(client)); } fn read_continously(client: Arc<Mutex<Client>>) -> ! { loop { { let mut client = client.lock().unwrap(); client.get_request().expect("get"); } thread::sleep(Duration::from_secs(READING_INTERVAL)); } } fn send_message(client: Arc<Mutex<Client>>) -> ! { let mut read_buf = String::with_capacity(MAX_USER_INPUT); let stdin = std::io::stdin(); let mut stdin = stdin.lock(); loop { let read = stdin.read_line(&mut read_buf).expect("read_line"); if read_buf.trim().is_empty() { let mut client = client.lock().unwrap(); client.get_request().expect("get"); } else { let mut client = client.lock().unwrap(); client.set_request(&read_buf[..read]).expect("set"); } read_buf.clear(); } } fn main() { let mut client = Client::connect_to_server().expect("connect"); client.handshake().expect("handshake"); let client = Arc::new(Mutex::new(client)); start_reader_thread(client.clone()); send_message(client); }