1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use std::{
    io::{self, Read, Write},
    net::TcpStream,
    sync::Arc,
    thread,
};

use clap::Parser;
use servers::server::MAX_PACKET_LEN;

#[derive(Debug, Parser)]
#[clap(
    name = "tcp-client",
    version = env!("CARGO_PKG_VERSION"),
    about = env!("CARGO_PKG_DESCRIPTION")
)]
struct Cli {
    #[clap(
        short = 'i',
        long = "host",
        help = "Server host",
        default_value = "0.0.0.0",
        display_order = 1
    )]
    host: String,

    #[clap(
        short = 'p',
        long = "port",
        help = "Server port",
        default_value = "9999",
        display_order = 2
    )]
    port: String,
}

fn main() -> anyhow::Result<()> {
    let args = Cli::parse();

    let addr = format!("{}:{}", args.host, args.port);

    println!("Connecting to {}...", addr);

    let stream = TcpStream::connect(addr)?;

    println!("Connected!");

    let stream = Arc::new(stream);

    let reader = stream.clone();
    let writer = stream;

    // read the output from the server to write to the stdout
    thread::spawn(move || {
        let mut buf = [0; MAX_PACKET_LEN];

        // read buffer from the server
        while let Ok(buf_len) = reader.as_ref().read(&mut buf) {
            // ignore unused bytes
            let buf = &buf[0..buf_len];

            // decode buffer from &[u8] to a String
            let mut buf_str = String::from_utf8(buf.to_vec()).unwrap();

            // delete new line characters from the buffer
            buf_str = buf_str.replace('\n', "");
            buf_str = buf_str.replace('\r', "");

            println!("{}", buf_str);
        }
    });

    // create a new stdin handler
    let stdin = io::stdin();

    // send command from stdin
    loop {
        let mut buf = String::new();

        // read buffer from stdin
        stdin.read_line(&mut buf)?;

        // remove new line characters
        while buf.ends_with('\n') || buf.ends_with('\r') {
            buf.pop();
        }

        // send the buffer to the server
        writer.as_ref().write_all(buf.as_bytes())?;
    }
}