Initial codebase basically copied from https://github.com/tensor-programming/Rust_client-server_chat unsure how much of that will remain though
parent
c8bf78ea5d
commit
ed4602ad21
|
@ -0,0 +1,7 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hermit-chat"
|
||||||
|
version = "0.1.0"
|
108
src/main.rs
108
src/main.rs
|
@ -1,3 +1,12 @@
|
||||||
|
use std::env;
|
||||||
|
use std::io::{self, ErrorKind, Read, Write};
|
||||||
|
use std::net::{TcpStream, TcpListener};
|
||||||
|
use std::sync::mpsc::{self, TryRecvError};
|
||||||
|
use std::thread;
|
||||||
|
|
||||||
|
const LOCAL_HOST: &str = "127.0.0.1:6000";
|
||||||
|
const MESSAGE_SIZE: usize = 32;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: Vec<String> = env::args().collect();
|
let args: Vec<String> = env::args().collect();
|
||||||
let query = &args[args.len() - 1];
|
let query = &args[args.len() - 1];
|
||||||
|
@ -7,12 +16,61 @@ fn main() {
|
||||||
} else if query == "--bridge"{
|
} else if query == "--bridge"{
|
||||||
launch_bridge();
|
launch_bridge();
|
||||||
} else {
|
} else {
|
||||||
|
launch_client();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn sleep() {
|
||||||
|
thread::sleep(::std::time::Duration::from_millis(100));
|
||||||
|
}
|
||||||
|
|
||||||
// Yup thats uh a "server" uhuh it sure serves it's purpose I think I hope
|
// Yup thats uh a "server" uhuh it sure serves it's purpose I think I hope
|
||||||
fn launch_server() {
|
fn launch_server() {
|
||||||
|
let server = TcpListener::bind(LOCAL_HOST).expect("Listener failed to bind");
|
||||||
|
server.set_nonblocking(true).expect("Failed to initialize non-blocking");
|
||||||
|
|
||||||
|
let mut clients = vec![];
|
||||||
|
let (tx, rx) = mpsc::channel::<String>();
|
||||||
|
loop {
|
||||||
|
if let Ok((mut socket, address)) = server.accept() {
|
||||||
|
println!("Client {} connected", address);
|
||||||
|
|
||||||
|
let tx = tx.clone();
|
||||||
|
clients.push(socket.try_clone().expect("Failed to clone client"));
|
||||||
|
|
||||||
|
thread::spawn(move || loop {
|
||||||
|
let mut buffer = vec![0; MESSAGE_SIZE];
|
||||||
|
|
||||||
|
match socket.read_exact(&mut buffer) {
|
||||||
|
Ok(_) => {
|
||||||
|
let message = buffer.into_iter().take_while(|&x| x != 0).collect::<Vec<_>>();
|
||||||
|
let message = String::from_utf8(message).expect("Invalid utf8 message");
|
||||||
|
|
||||||
|
println!("{}: {:?}", address, message);
|
||||||
|
tx.send(message).expect("Failed to send message to rx");
|
||||||
|
},
|
||||||
|
Err(ref error) if error.kind() == ErrorKind::WouldBlock => (),
|
||||||
|
Err(_) => {
|
||||||
|
println!("Closing connection with: {}", address);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(message) = rx.try_recv() {
|
||||||
|
clients = clients.into_iter().filter_map(|mut client| {
|
||||||
|
let mut buffer = message.clone().into_bytes();
|
||||||
|
buffer.resize(MESSAGE_SIZE, 0);
|
||||||
|
|
||||||
|
client.write_all(&buffer).map(|_| client).ok()
|
||||||
|
}).collect::<Vec<_>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// A bridge is basically the same as a client but can also be connected to on the local computer
|
// A bridge is basically the same as a client but can also be connected to on the local computer
|
||||||
|
@ -23,4 +81,52 @@ fn launch_bridge() {
|
||||||
//I can yap in comments all I want if you want to complain use this function to talk to me on my
|
//I can yap in comments all I want if you want to complain use this function to talk to me on my
|
||||||
//hermitchat server k thx
|
//hermitchat server k thx
|
||||||
fn launch_client() {
|
fn launch_client() {
|
||||||
|
let mut client = TcpStream::connect(LOCAL_HOST).expect("Stream failed to connect");
|
||||||
|
client.set_nonblocking(true).expect("Failed to initiate non-blocking");
|
||||||
|
|
||||||
|
let (tx, rx) = mpsc::channel::<String>();
|
||||||
|
|
||||||
|
thread::spawn(move || loop {
|
||||||
|
let mut buffer = vec![0; MESSAGE_SIZE];
|
||||||
|
|
||||||
|
match client.read_exact(&mut buffer) {
|
||||||
|
Ok(_) => {
|
||||||
|
let message = buffer.into_iter().into_iter().take_while(|&x| x != 0).collect::<Vec<_>>();
|
||||||
|
println!("Message recv {:?}", message);
|
||||||
|
}
|
||||||
|
Err(ref error) if error.kind() == ErrorKind::WouldBlock => (),
|
||||||
|
Err(_) => {
|
||||||
|
println!("Connection with server was severed");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match rx.try_recv() {
|
||||||
|
Ok(message) => {
|
||||||
|
let mut buffer = message.clone().into_bytes();
|
||||||
|
buffer.resize(MESSAGE_SIZE, 0);
|
||||||
|
client.write_all(&buffer).expect("Writing to socket failed");
|
||||||
|
println!("Message sent {:?}", message);
|
||||||
|
},
|
||||||
|
Err(TryRecvError::Empty) => (),
|
||||||
|
Err(TryRecvError::Disconnected) => break
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep();
|
||||||
|
});
|
||||||
|
|
||||||
|
println!("Write a message:");
|
||||||
|
loop {
|
||||||
|
let mut buffer = String::new();
|
||||||
|
io::stdin().read_line(&mut buffer).expect("Line could not be read");
|
||||||
|
let message = buffer.trim().to_string();
|
||||||
|
if message == "/exit" {
|
||||||
|
println!("Quiting!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if tx.send(message).is_err() {
|
||||||
|
println!("Could not send message");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue