This commit is contained in:
Emma Tebibyte 2023-06-17 14:30:53 -06:00
parent ed09e931c7
commit 410c0d5068
Signed by untrusted user: emma
GPG Key ID: 6D661C738815E7DD
2 changed files with 180 additions and 72 deletions

View File

@ -17,90 +17,75 @@
*/
use std::{
io::Read,
net::{ TcpListener, TcpStream },
thread,
io::{ self, BufRead, BufReader, Write },
net::{ TcpListener, TcpStream },
thread,
};
use serde_derive::Deserialize;
#[derive(Debug, Deserialize)]
struct MessageOuter {
auth: Option<String>,
message: Message,
to: String,
}
#[derive(Debug, Deserialize)]
struct Message {
body: String,
from: Option<String>,
from: Option<String>,
body: Option<String>,
}
fn parse_message(input: &str) -> MessageOuter {
let mut auth: Option<String> = None;
let mut body = String::new();
let mut from = None;
let mut to = String::new();
fn handle_client(stream: TcpStream) {
let mut reader = BufReader::new(&stream);
let mut writer = &stream;
for line in input.lines() {
let mut parts = line.split_whitespace();
if let Some(field) = parts.next() {
if let Some(value) = parts.next() {
match field {
"AUTH" => auth = Some(value.to_string()),
"BODY" => body = value.to_string(),
"FROM" => from = Some(value.to_string()),
"TO" => to = value.to_string(),
_ => {},
}
}
}
}
let mut message = Message {
from: None,
body: None,
};
let message_outer = MessageOuter {
auth,
message: Message { body, from },
to,
};
loop {
let mut send = false;
let mut buffer = String::new();
if reader.read_line(&mut buffer).is_err() {
println!(
"{} disconnected.",
message.from.unwrap_or_else(|| { format!("anon") }),
);
break;
}
message_outer
}
let words: Vec<&str> = buffer.split_whitespace().collect();
if words.is_empty() {
continue;
}
fn read_from(mut stream: TcpStream) {
let mut buf = Vec::new();
match words[0] {
"FROM" => {
message.from = Some(words[1..].join(" "));
}
"BODY" => {
message.body = Some(words[1..].join(" "));
send = true;
}
_ => {}
}
while let Ok(bytes_read) = stream.read_to_end(&mut buf) {
if bytes_read == 0 { break }
let message_outer = parse_message(
String::from_utf8(buf.clone()).as_ref().unwrap()
);
let user = message_outer.message.from.unwrap_or_else(|| {
format!("anon")
});
println!("{}: {}", user, message_outer.message.body);
}
if send {
println!(
"{}: {}",
message.from.clone().unwrap_or_else(|| { format!("anon") }),
message.body.take().unwrap(),
);
}
}
}
fn main() {
let listener = TcpListener::bind("127.0.0.1:8080")
.expect("Failed to bind address");
let listener = TcpListener::bind("0.0.0.0:8080")
.expect("Failed to bind to port 8080.");
println!("Server listening on port 8080.");
println!("Server listening on 127.0.0.1:8080");
for stream in listener.incoming() {
match stream {
Ok(stream) => {
thread::spawn(move || {
read_from(stream);
});
}
Err(err) => {
eprintln!("Error accepting client connection: {}", err);
}
}
}
for stream in listener.incoming() {
match stream {
Ok(stream) => {
thread::spawn(move || handle_client(stream));
}
Err(e) => {
eprintln!("Error accepting client connection: {}", e);
}
}
}
}

123
temp.rs Normal file
View File

@ -0,0 +1,123 @@
use std::io::{Read, Write};
use std::net::{TcpListener, TcpStream};
use std::sync::{Arc, Mutex};
use std::thread;
#[derive(Debug, Deserialize)]
struct MessageOuter {
auth: Option<String>,
message: Message,
to: String,
}
#[derive(Debug, Deserialize)]
struct Message {
body: String,
from: Option<String>,
}
fn parse_message(input: &str) -> MessageOuter {
let mut auth: Option<String> = None;
let mut body = String::new();
let mut from = None;
let mut to = String::new();
for line in input.lines() {
let mut parts = line.split_whitespace();
if let Some(field) = parts.next() {
if let Some(value) = parts.next() {
match field {
"AUTH" => auth = Some(value.to_string()),
"BODY" => body = value.to_string(),
"FROM" => from = Some(value.to_string()),
"TO" => to = value.to_string(),
_ => {}
}
}
}
}
let message_outer = MessageOuter {
auth,
message: Message { body, from },
to,
};
message_outer
}
fn read_from(mut stream: TcpStream) -> MessageOuter {
let mut buf = Vec::new();
let mut message_outer = MessageOuter {
auth: None,
message: Message {
body: "".to_string(),
from: None,
},
to: "".to_string(),
};
while let Ok(bytes_read) = stream.read_to_end(&mut buf) {
if bytes_read == 0 {
break;
}
message_outer = parse_message(
String::from_utf8(buf.clone()).as_ref().unwrap()
);
}
message_outer.message.from = Some(
message_outer.message.from.unwrap_or_else(|| "anon".to_string())
);
message_outer
}
fn main() {
let listener = TcpListener::bind("127.0.0.1:8080")
.expect("Failed to bind address");
println!("Server listening on 127.0.0.1:8080");
let client_list: Arc<Mutex<Vec<TcpStream>>> = Arc::new(
Mutex::new(vec![])
);
for stream in listener.incoming() {
match stream {
Ok(stream) => {
let client_list = Arc::clone(&client_list);
thread::spawn(move || {
// Add the client's stream to the client list
client_list.lock().unwrap().push(stream.try_clone().unwrap());
let message = read_from(stream);
// Send the received message to all connected clients
let serialized_message = serde_json::to_string(&message).unwrap();
let client_list = client_list.lock().unwrap();
for client in &*client_list {
if let Err(e) = client.write_all(serialized_message.as_bytes()) {
eprintln!("Failed to write to client: {}", e);
}
if let Err(e) = client.flush() {
eprintln!("Failed to flush stream: {}", e);
}
}
// Remove the client's stream from the client list
client_list
.lock()
.unwrap()
.retain(|client| client
.peer_addr()
.unwrap() != stream.peer_addr().unwrap());
});
}
Err(err) => {
eprintln!("Error accepting client connection: {}");
}
}
}
}