Skip to content

Instantly share code, notes, and snippets.

@vishalg0wda
Created December 2, 2024 15:37
Show Gist options
  • Save vishalg0wda/a2a7288145b98bc6eb13249781fb613e to your computer and use it in GitHub Desktop.
Save vishalg0wda/a2a7288145b98bc6eb13249781fb613e to your computer and use it in GitHub Desktop.
R/w of newline delimited messages over a TCP Socket in Rust
use std::io::{BufRead, BufReader, BufWriter, Read, Write};
use std::net::{Shutdown, SocketAddr, TcpListener, TcpStream};
fn server(addr: SocketAddr) {
let listener = TcpListener::bind(addr).unwrap();
let (con, _) = listener.accept().unwrap();
let reader = BufReader::new(&con);
let mut writer = BufWriter::new(&con);
for msg in reader.lines() {
let Ok(msg) = msg else {
eprintln!("unable to parse message frame, {:?}", msg.err().unwrap());
continue;
};
println!("MSG: {msg:>10}");
match msg.as_str() {
"ping" => {
writer.write_all("pong\n".as_bytes()).unwrap();
writer.flush().unwrap();
}
"pong" => {
writer.write_all("ping\n".as_bytes()).unwrap();
writer.flush().unwrap();
}
_ => {
con.shutdown(Shutdown::Both).unwrap();
break;
}
};
}
}
fn client(addr: SocketAddr, inp: impl Read, out: impl Write) {
let con = TcpStream::connect(addr).unwrap();
let mut tcp_reader = BufReader::new(&con);
let mut tcp_writer = BufWriter::new(&con);
let mut inp_reader = BufReader::new(inp);
let mut out_writer = BufWriter::new(out);
loop {
out_writer.write("> ".as_bytes()).unwrap();
out_writer.flush().unwrap();
let mut line = String::new();
if inp_reader.read_line(&mut line).unwrap() == 0 {
eprintln!("reached EOF");
break;
};
// send message
tcp_writer.write_all(line.as_bytes()).unwrap();
tcp_writer.flush().unwrap();
// receive reply
let mut line = String::new();
if tcp_reader.read_line(&mut line).unwrap() == 0 {
break;
}
out_writer
.write_all(format!("REPLY: {}\n", line).as_bytes())
.unwrap();
out_writer.flush().unwrap();
}
}
fn main() {
let mode = std::env::args().last().unwrap();
let addr: SocketAddr = "127.0.0.1:8080".parse().unwrap();
match mode.as_str() {
"client" => client(
addr.into(),
std::io::stdin().lock(),
std::io::stdout().lock(),
),
"server" => server(addr.into()),
_ => panic!("invalid mode '{}' supplied", mode),
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment