From 8f2850445b7f10260b33dfc715a699c32fda81c6 Mon Sep 17 00:00:00 2001 From: emma Date: Thu, 22 Jun 2023 23:26:26 -0600 Subject: [PATCH] initial client code --- Cargo.lock | 32 +------------------------ Cargo.toml | 10 ++++++-- src/client.rs | 52 +++++++++++++++++++++++++++++++++++++++++ src/{main.rs => lib.rs} | 27 ++------------------- src/server.rs | 49 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 58 deletions(-) create mode 100644 src/client.rs rename src/{main.rs => lib.rs} (79%) create mode 100644 src/server.rs diff --git a/Cargo.lock b/Cargo.lock index 8324567..02c61b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,7 +20,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 1.0.109", + "syn", "which", ] @@ -100,8 +100,6 @@ dependencies = [ name = "liminality" version = "0.0.1" dependencies = [ - "serde", - "serde_derive", "yacexits", ] @@ -187,23 +185,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "serde" -version = "1.0.164" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" - -[[package]] -name = "serde_derive" -version = "1.0.164" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.12", -] - [[package]] name = "shlex" version = "1.1.0" @@ -221,17 +202,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "syn" -version = "2.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "unicode-ident" version = "1.0.8" diff --git a/Cargo.toml b/Cargo.toml index e004623..92ec5b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,12 @@ license = "AGPL-3.0-or-later" authors = [ "Emma Tebibyte " ] [dependencies] -serde = "1.0.164" -serde_derive = "1.0.164" yacexits = "0.1.5" + +[[bin]] +name = "server" +path = "src/server.rs" + +[[bin]] +name = "client" +path = "src/client.rs" diff --git a/src/client.rs b/src/client.rs new file mode 100644 index 0000000..4de4ae6 --- /dev/null +++ b/src/client.rs @@ -0,0 +1,52 @@ +use std::{ + env::args, + io::{ BufRead, BufReader, stdin, Write }, + net::TcpStream, + thread, +}; + +use yacexits::exit; + +fn main() { + let args = args().collect::>(); + let argv = args.iter().map(String::as_str).collect::>(); + + if !argv.clone().get(1).is_some() || !argv.clone().get(2).is_some() { + exit(1); + } + + let user = argv[2]; + + let mut stream = TcpStream::connect(argv[1]).unwrap_or_else(|err| { + eprintln!("{:?}", err); + exit(1); + }); + + let from_message = format!("FROM {}\n", user); + + let _ = stream.write(from_message.as_bytes()); + + let stream_recv = stream.try_clone().unwrap(); + + let _ = thread::spawn(move || { + let reader = BufReader::new(stream_recv); + + for line in reader.lines() { + if let Ok(message) = line { + let words: Vec<&str> = message.split_whitespace().collect(); + match words[0] { + "FROM" => print!("{}: ", words[1..].join(" ")), + "BODY" => println!("{}", words[1..].join(" ")), + _ => {}, + } + } + } + }); + + loop { + let mut buf = String::new(); + let _ = stdin().read_line(&mut buf); + let out = format!("BODY {}\n", buf); + let _ = stream.write(out.as_bytes()); + } +} diff --git a/src/main.rs b/src/lib.rs similarity index 79% rename from src/main.rs rename to src/lib.rs index 0a7459d..89c6eef 100644 --- a/src/main.rs +++ b/src/lib.rs @@ -19,9 +19,8 @@ use std::{ collections::HashMap, io::{ BufRead, BufReader, Write }, - net::{ TcpListener, TcpStream }, + net::TcpStream, sync::{ Arc, Mutex }, - thread, }; struct Message { @@ -29,7 +28,7 @@ struct Message { body: Option, } -fn handle_client( +pub fn handle_client( client: usize, clients: Arc>> ) { @@ -107,25 +106,3 @@ fn handle_client( } } -fn main() { - let listener = TcpListener::bind("0.0.0.0:8080") - .expect("Failed to bind to port 8080."); - println!("Server listening on port 8080."); - - let connections: Arc>> = Arc::new( - Mutex::new(HashMap::new()) - ); - - for (id, stream) in listener.incoming().enumerate() { - match stream { - Ok(stream) => { - let clients = connections.clone(); - clients.lock().unwrap().insert(id.clone(), stream); - thread::spawn(move || handle_client(id, clients)); - } - Err(err) => { - eprintln!("Error accepting client connection: {}", err); - } - } - } -} diff --git a/src/server.rs b/src/server.rs new file mode 100644 index 0000000..be236cf --- /dev/null +++ b/src/server.rs @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Emma Tebibyte + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify it under + * the terms of the GNU Affero General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more + * details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see https://www.gnu.org/licenses/. + */ + +use std::{ + collections::HashMap, + net::{ TcpListener, TcpStream }, + sync::{ Arc, Mutex }, + thread, +}; + +use liminality::handle_client; + +fn main() { + let listener = TcpListener::bind("0.0.0.0:8080") + .expect("Failed to bind to port 8080."); + println!("Server listening on port 8080."); + + let connections: Arc>> = Arc::new( + Mutex::new(HashMap::new()) + ); + + for (id, stream) in listener.incoming().enumerate() { + match stream { + Ok(stream) => { + let clients = connections.clone(); + clients.lock().unwrap().insert(id.clone(), stream); + thread::spawn(move || handle_client(id, clients)); + } + Err(err) => { + eprintln!("Error accepting client connection: {}", err); + } + } + } +}