A client connects to a service using TcpStream::connect()
where the service is specified as host:port
.
It can then read and write bytes to the returned stream.
The client is
/EchoClient.rs:
use std::io::{self, Read, Write, BufRead};
use std::net::TcpStream;
use std::env;
use std::str;
use std::io::stdout;
fn main() -> std::io::Result<()> {
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
println!("Usage {} hostname", args[0]);
std::process::exit(1);
}
let hostname = &args[1];
let mut stream = TcpStream::connect(hostname.to_string() + &":2000")
.expect("Couldn't connect to the server...");
// from https://stackoverflow.com/questions/30186037/how-can-i-read-a-single-line-from-stdin
print!("Enter line:"); stdout().flush();
let stdin = io::stdin();
for line in stdin.lock().lines() {
let line = line.unwrap();
println!("Read line: '{}'", line);
if &line == "BYE" {
break;
}
stream.write(line.as_bytes())
.expect("Error on write");
let mut echo_bytes: [u8; 2048] = [0; 2048];
stream.read(&mut echo_bytes[..])
.expect("Error on read");
let echo = str::from_utf8(&echo_bytes).unwrap();
println!("Echoed: '{}'", echo);
print!("Enter line:"); stdout().flush();
}
Ok(())
} // the stream is closed here
The server binds to ANY host and listens by TcpListener::bind()
.
It accepts a connection using incoming
and can then read and
write from the resultant stream.
If the server wants to listen to IPv4 only, then the ANY host is "0.0.0.0".
If it is running a dual IPv4/IPv6 stack, then the ANY host should be "::"
(enclosed as "[::}" to avoid confusion with the ':' in "host:port")
for both IPv4 and IPv6.
The program is
/EchoServer.rs:
// From https://gist.github.com/fortruce/828bcc3499eb291e7e17
use std::net::{TcpListener, TcpStream};
use std::thread;
use std::io::Read;
use std::io::Write;
fn handle_client(mut stream: TcpStream) {
println!("Connected");
// read 2048 bytes at a time from stream echoing back to stream
loop {
let mut read = [0; 2048];
match stream.read(&mut read) {
Ok(n) => {
if n == 0 {
// connection was closed
break;
}
stream.write(&read[0..n]).unwrap();
}
Err(_err) => {
//panic!(err);
break;
}
}
}
println!("Disconnected");
}
fn main() {
//let listener = TcpListener::bind("0.0.0.0:2000").unwrap();
let listener = TcpListener::bind("[::]:2000").unwrap();
for stream in listener.incoming() {
match stream {
Ok(stream) => {
thread::spawn(move || {
handle_client(stream);
});
}
Err(_) => {
println!("Error");
}
}
}
}
Copyright © Jan Newmarch, jan@newmarch.name
" Network Programming using Java, Go, Python, Rust, JavaScript and Julia"
by
Jan Newmarch
is licensed under a
Creative Commons Attribution-ShareAlike 4.0 International License
.
Based on a work at
https://jan.newmarch.name/NetworkProgramming/
.