demo completed

This commit is contained in:
Alexey 2025-11-19 11:23:16 +03:00
commit 1145cd4eba
2 changed files with 81 additions and 15 deletions

60
src/bin/client.rs Normal file
View file

@ -0,0 +1,60 @@
use std::{io::{Read, Write}, os::unix::net::UnixStream};
fn stream_read(stream: &mut UnixStream, buf: &mut [u8]) -> String {
if let Err(err) = stream.read(buf) {
eprintln!("Error while reading: {err}");
if let Err(shuterr) = stream.shutdown(std::net::Shutdown::Both) {
eprintln!("Error while shutting down: {shuterr}");
}
return String::new();
}
let mut string = match str::from_utf8(buf) {
Ok(str) => str.to_owned(),
Err(err) => {
eprintln!("Error while parsing utf-8: {err}");
String::new()
}
};
string.retain(|c| c != '\n' && c != '\0');
string
}
fn main() -> std::io::Result<()> {
let stream = UnixStream::connect("/tmp/rustsock");
if let Err(err) = stream {
return Err(err);
}
let mut stream = stream.unwrap();
let mut buf = [0u8; 64];
let mut response = String::new();
// Read first message from listener
response = stream_read(&mut stream, &mut buf);
if !response.is_empty() {
println!("{response}");
}
loop {
// Send user input
let mut input = String::new();
std::io::stdin().read_line(&mut input)?;
input = input.trim().to_owned();
stream.write_all(input.as_bytes())?;
// Receive message from listener
buf = [0u8; 64];
response = stream_read(&mut stream, &mut buf);
if !response.is_empty() {
println!("{response}");
}
if response == "CON CLOSED" {
break;
}
}
Ok(())
}

View file

@ -22,10 +22,13 @@ fn stream_read<'a>(stream: &'a mut UnixStream, buf: &'a mut [u8], state: &mut Co
stream_shutdown(stream, state);
}
match str::from_utf8(&buf) {
let mut string = match str::from_utf8(&buf) {
Ok(str) => str.to_owned(),
Err(_) => String::new()
}
};
string.retain(|c| c != '\n' && c != '\0');
string
}
enum ConnectionState {
@ -38,7 +41,7 @@ fn handle_client(mut stream: UnixStream) {
let mut buf: [u8; 64];
let mut state = ConnectionState::Initialized;
let mut cnt = 0usize;
stream_write(&mut stream, b"ID THYSELF\n", &mut state);
stream_write(&mut stream, b"ID THYSELF", &mut state);
loop {
buf = [0; 64];
@ -51,7 +54,7 @@ fn handle_client(mut stream: UnixStream) {
println!("recv: {string}");
if string.starts_with("END") {
stream_write(&mut stream, b"CON CLOSED\n", &mut state);
stream_write(&mut stream, b"CON CLOSED", &mut state);
stream_shutdown(&stream, &mut state);
break;
}
@ -60,11 +63,11 @@ fn handle_client(mut stream: UnixStream) {
match &state {
ConnectionState::Initialized => {
state = ConnectionState::Identified(string.to_owned());
stream_write(&mut stream, b"WELCOME\n", &mut state);
stream_write(&mut stream, b"WELCOME", &mut state);
}
ConnectionState::Identified(name) => {
if string.starts_with("HI") {
stream_write(&mut stream, format!("HELLO {}\n", name).as_bytes() , &mut state);
if string == "HI" {
stream_write(&mut stream, format!("HELLO {}", name).as_bytes() , &mut state);
continue;
}
@ -75,29 +78,29 @@ fn handle_client(mut stream: UnixStream) {
match numstr.parse::<usize>() {
Ok(num) => {
cnt = num;
stream_write(&mut stream, b"SET OK\n", &mut state);
stream_write(&mut stream, b"SET OK", &mut state);
}
Err(_) => {
stream_write(&mut stream, b"INCOR USIZE\n", &mut state);
stream_write(&mut stream, b"INCOR USIZE", &mut state);
}
}
} else {
stream_write(&mut stream, b"NOT ENOUGH ARGS\n", &mut state);
stream_write(&mut stream, b"NOT ENOUGH ARGS", &mut state);
}
continue;
}
if string.starts_with("ECHO") {
stream_write(&mut stream, format!("CNT={cnt}\n").as_bytes(), &mut state);
if string == "ECHO" {
stream_write(&mut stream, format!("CNT={cnt}").as_bytes(), &mut state);
continue;
}
if string.starts_with("HELP") {
stream_write(&mut stream, b"AVAIL: ECHO; END; HELP; HI; SET N\n", &mut state);
if string == "HELP" {
stream_write(&mut stream, b"AVAIL: ECHO; END; HELP; HI; SET N", &mut state);
continue;
}
stream_write(&mut stream, b"UNDEF; TRY HELP\n", &mut state);
stream_write(&mut stream, b"UNDEF; TRY HELP", &mut state);
}
ConnectionState::Shutdown => break
}
@ -105,6 +108,9 @@ fn handle_client(mut stream: UnixStream) {
}
fn main() -> std::io::Result<()> {
if std::fs::exists("/tmp/rustsock")? {
std::fs::remove_file("/tmp/rustsock")?;
}
let listener = UnixListener::bind("/tmp/rustsock")?;
for stream in listener.incoming() {