Created
December 2, 2024 15:37
-
-
Save vishalg0wda/a2a7288145b98bc6eb13249781fb613e to your computer and use it in GitHub Desktop.
R/w of newline delimited messages over a TCP Socket in Rust
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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