Skip to content
Snippets Groups Projects

bs-9R-client2-rs

  • Clone with SSH
  • Clone with HTTPS
  • Embed
  • Share
    The snippet can be accessed without any authentication.
    Authored by Kai Bleeke
    client2.rs 3.43 KiB
    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);
    }
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment