init
This commit is contained in:
commit
4b8cd6f6d4
4 changed files with 138 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/target
|
||||||
7
Cargo.lock
generated
Normal file
7
Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "socket_test"
|
||||||
|
version = "0.1.0"
|
||||||
6
Cargo.toml
Normal file
6
Cargo.toml
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
[package]
|
||||||
|
name = "socket_test"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
124
src/main.rs
Normal file
124
src/main.rs
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
use std::{io::{Read, Write}, os::unix::net::{UnixListener, UnixStream}, thread};
|
||||||
|
|
||||||
|
fn stream_shutdown(stream: &UnixStream, state: &mut ConnectionState) {
|
||||||
|
if let Err(err) = stream.shutdown(std::net::Shutdown::Both) {
|
||||||
|
eprintln!("Stream shutdown error: {err}");
|
||||||
|
} else {
|
||||||
|
println!("Closed connection...");
|
||||||
|
}
|
||||||
|
*state = ConnectionState::Shutdown;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stream_write(stream: &mut UnixStream, bytes: &[u8], state: &mut ConnectionState) {
|
||||||
|
if let Err(err) = stream.write_all(bytes) {
|
||||||
|
eprintln!("Stream writing error: {err}");
|
||||||
|
stream_shutdown(stream, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stream_read<'a>(stream: &'a mut UnixStream, buf: &'a mut [u8], state: &mut ConnectionState) -> String {
|
||||||
|
if let Err(err) = stream.read(buf) {
|
||||||
|
eprintln!("Stream reading error: {err}");
|
||||||
|
stream_shutdown(stream, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
match str::from_utf8(&buf) {
|
||||||
|
Ok(str) => str.to_owned(),
|
||||||
|
Err(_) => String::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ConnectionState {
|
||||||
|
Initialized,
|
||||||
|
Identified(String),
|
||||||
|
Shutdown,
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
buf = [0; 64];
|
||||||
|
let string = stream_read(&mut stream, &mut buf, &mut state).to_owned();
|
||||||
|
|
||||||
|
if string.is_empty() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("recv: {string}");
|
||||||
|
|
||||||
|
if string.starts_with("END") {
|
||||||
|
stream_write(&mut stream, b"CON CLOSED\n", &mut state);
|
||||||
|
stream_shutdown(&stream, &mut state);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
match &state {
|
||||||
|
ConnectionState::Initialized => {
|
||||||
|
state = ConnectionState::Identified(string.to_owned());
|
||||||
|
stream_write(&mut stream, b"WELCOME\n", &mut state);
|
||||||
|
}
|
||||||
|
ConnectionState::Identified(name) => {
|
||||||
|
if string.starts_with("HI") {
|
||||||
|
stream_write(&mut stream, format!("HELLO {}\n", name).as_bytes() , &mut state);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if string.starts_with("SET ") {
|
||||||
|
let splitstr = string.split(' ').nth(1);
|
||||||
|
if let Some(numstr) = splitstr {
|
||||||
|
println!("{}", numstr);
|
||||||
|
match numstr.parse::<usize>() {
|
||||||
|
Ok(num) => {
|
||||||
|
cnt = num;
|
||||||
|
stream_write(&mut stream, b"SET OK\n", &mut state);
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
stream_write(&mut stream, b"INCOR USIZE\n", &mut state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stream_write(&mut stream, b"NOT ENOUGH ARGS\n", &mut state);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if string.starts_with("ECHO") {
|
||||||
|
stream_write(&mut stream, format!("CNT={cnt}\n").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);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream_write(&mut stream, b"UNDEF; TRY HELP\n", &mut state);
|
||||||
|
}
|
||||||
|
ConnectionState::Shutdown => break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> std::io::Result<()> {
|
||||||
|
let listener = UnixListener::bind("/tmp/rustsock")?;
|
||||||
|
|
||||||
|
for stream in listener.incoming() {
|
||||||
|
match stream {
|
||||||
|
Ok(stream) => {
|
||||||
|
println!("Received connection...");
|
||||||
|
thread::spawn(|| handle_client(stream));
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
eprintln!("Connection failed: {err}");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue