From ce45fb60ad4fe9d13accd8ea74ef7a7a4dbb979c Mon Sep 17 00:00:00 2001 From: Phuntsok Drak-pa Date: Mon, 5 Mar 2018 17:39:11 +0100 Subject: [PATCH] Updated, but client still doesn't display text --- Lucien/Rust/Cargo.toml | 5 +- Lucien/Rust/src/client.rs | 109 ++++++++++++++++++++++++----- Lucien/Rust/src/main.rs | 4 +- Lucien/Rust/src/server.rs | 142 +++++++++++++++++++++----------------- 4 files changed, 174 insertions(+), 86 deletions(-) diff --git a/Lucien/Rust/Cargo.toml b/Lucien/Rust/Cargo.toml index e4201bc..7e36bbf 100644 --- a/Lucien/Rust/Cargo.toml +++ b/Lucien/Rust/Cargo.toml @@ -1,6 +1,7 @@ [package] name = "chat-reseau" -version = "0.1.0" -authors = ["Phuntsok Drak-pa "] +version = "0.2.0" +authors = ["Lucien Cartier-Tilet "] [dependencies] +bufstream = "0.1" diff --git a/Lucien/Rust/src/client.rs b/Lucien/Rust/src/client.rs index 0a7a0e1..1c5c328 100644 --- a/Lucien/Rust/src/client.rs +++ b/Lucien/Rust/src/client.rs @@ -1,6 +1,10 @@ +extern crate bufstream; use std::net::TcpStream; -use std::io::{Read, Write}; -use std::io::{stdin, stdout}; +use std::io::{stdin, stdout, Read, Write}; +// use std::sync::mpsc; +// use std::sync::mpsc::{Receiver, Sender}; +use std::thread::spawn; +// use self::bufstream::BufStream; fn get_entry() -> String { let mut buf = String::new(); @@ -9,12 +13,51 @@ fn get_entry() -> String { buf.replace("\n", "").replace("\r", "") } -fn exchange_with_server(mut stream: TcpStream) { +fn read_from_server( + mut stream: TcpStream, +) { + let buff = &mut [0; 1024]; let stdout = stdout(); let mut io = stdout.lock(); - let buf = &mut [0; 1024]; + loop { + match stream.read(buff) { + Ok(received) => { + if received < 1 { + // println!("Perte de connexion avec le serveur"); + write!(io, "Perte de connexion avec le serveur\n").unwrap(); + io.flush().unwrap(); + return; + } + } + Err(_) => { + // println!("Perte de connexion avec le serveur"); + write!(io, "Perte de connexion avec le serveur\n").unwrap(); + io.flush().unwrap(); + return; + } + } + let reponse = String::from_utf8(buff.to_vec()).unwrap(); + write!(io, "{}", reponse).unwrap(); + io.flush().unwrap(); + // println!("From server: {}", reponse); + } +} + +fn exchange_with_server( + mut stream: TcpStream +) { + let stdout = stdout(); + let mut io = stdout.lock(); + let _buff = &mut [0; 1024]; + + let stream_cpy = stream.try_clone().unwrap(); + spawn(move || { + // let stream_cpy = stream.try_clone().unwrap(); + read_from_server(stream_cpy); + }); + + println!("Enter `quit` or `exit` when you want to leave"); - println!("Enter `quit` when you want to leave"); loop { write!(io, "> ").unwrap(); io.flush().unwrap(); @@ -29,26 +72,53 @@ fn exchange_with_server(mut stream: TcpStream) { } line => { write!(stream, "{}\n", line).unwrap(); - match stream.read(buf) { - Ok(received) => { - if received < 1 { - println!("Perte de la connexion avec le serveur"); - return; - } - } - Err(_) => { - println!("Perte de la connexion avec le serveur"); - return; - } - } + // match stream.read(buff) { + // Ok(received) => { + // if received < 1 { + // println!("Perte de la connexion avec le serveur"); + // return; + // } + // } + // Err(_) => { + // println!("Perte de la connexion avec le serveur"); + // return; + // } + // } // println!("Réponse du serveur : {}", buf); - let reponse = String::from_utf8(buf.to_vec()).unwrap(); - println!("Réponse du serveur : {}", reponse); + // let reponse = String::from_utf8(buf.to_vec()).unwrap(); + // println!("Réponse du serveur : {}", reponse); } } } } +// fn exchange_with_server(stream: TcpStream) { +// let (chan, recv): (Sender, Receiver) = mpsc::channel(); +// // let buf = &mut [0; 1024]; +// spawn(move || { +// loop { +// let msg = recv.recv().unwrap(); +// println!("{}", msg); +// } +// }); +// println!("Enter `quit` or `exit` when you want to leave"); +// loop { +// match &*get_entry() { +// "quit" => { +// println!("bye!"); +// return; +// } +// "exit" => { +// println!("bye!"); +// return; +// } +// line => { +// chan.send(format!("{}", line)).unwrap(); +// } +// } +// } +// } + pub fn client(server_address: String) { println!("Tentative de connexion a serveur..."); match TcpStream::connect(server_address) { @@ -58,6 +128,7 @@ pub fn client(server_address: String) { } Err(e) => { println!("La connection au serveur a échoué : {}", e); + return; } } } diff --git a/Lucien/Rust/src/main.rs b/Lucien/Rust/src/main.rs index ad25480..7aa08a4 100644 --- a/Lucien/Rust/src/main.rs +++ b/Lucien/Rust/src/main.rs @@ -11,7 +11,9 @@ fn main() { /////////////////////////////////////////////////////////////////////// println!("Opening server on port {}", args[1]); // serveur(args[1].clone()); - server::serveur(args[1].clone()); + let mut serv = String::from("127.0.0.1:"); + serv.push_str(&args[1]); + server::serveur(serv); } else if args.len() == 3 { /////////////////////////////////////////////////////////////////////// // Client opened // diff --git a/Lucien/Rust/src/server.rs b/Lucien/Rust/src/server.rs index aa26b7a..7e358f4 100644 --- a/Lucien/Rust/src/server.rs +++ b/Lucien/Rust/src/server.rs @@ -1,78 +1,92 @@ -use std::net::{TcpListener, TcpStream}; -use std::io::{Read, Write}; -use std::thread; +extern crate bufstream; +use std::io::{BufRead, Write}; +use std::net::{SocketAddr, TcpListener, TcpStream}; +use std::str::FromStr; +use std::sync::{mpsc, Arc, RwLock}; +use std::sync::mpsc::{Receiver, Sender}; +use std::thread::spawn; +use self::bufstream::BufStream; -fn handle_client(mut stream: &TcpStream, adresse: &str, name: String) { - let mut msg: Vec = Vec::new(); +fn handle_connection( + stream: &mut BufStream, + chan: Sender, + arc: Arc>>, +) { + stream.write(b"Welcome this server!\n").unwrap(); + stream + .write(b"Please input your username (max. 20chars): ") + .unwrap(); + stream.flush().unwrap(); + + let mut name = String::new(); + stream.read_line(&mut name).unwrap(); + let name = name.trim_right(); + stream + .write_fmt(format_args!("Hello, {}!\n", name)) + .unwrap(); + stream.flush().unwrap(); + + let mut pos = 0; loop { - let buf = &mut [0; 10]; - - match stream.read(buf) { - Ok(received) => { - // si on a reçu 0 octet, ça veut dire que le client s'est déconnecté - if received < 1 { - println!("Client disconnected {}", adresse); - return; - } - let mut x = 0; - - for c in buf { - // si on a dépassé le nombre d'octets reçus, inutile de continuer - if x >= received { - break; - } - x += 1; - if *c == '\n' as u8 { - println!( - "message reçu {}({}) : {}", - name, - adresse, - // on convertit maintenant notre buffer en String - String::from_utf8(msg).unwrap() - ); - - stream.write(b"ok\n").unwrap(); - - msg = Vec::new(); - } else { - msg.push(*c); - } - } - } - Err(_) => { - println!("Client disconnected {}", adresse); - return; + { + let lines = arc.read().unwrap(); + for i in pos..lines.len() { + stream.write_fmt(format_args!("{}", lines[i])).unwrap(); + pos = lines.len(); } } + stream.write(b" > ").unwrap(); + stream.flush().unwrap(); + + let mut reads = String::new(); + stream.read_line(&mut reads).unwrap(); + if reads.trim().len() != 0 { + chan.send(format!("[{}] said: {}", name, reads)).unwrap(); + } } } -pub fn serveur(port: String) { - println!("Port: {}", port); - let mut serv = String::from("127.0.0.1:"); - serv.push_str(&port); - let listener = TcpListener::bind(serv.to_string()).unwrap(); +pub fn serveur(addr: String) { + // Ouverture de la connexion sur socket + let addr = SocketAddr::from_str(&addr).unwrap(); + // Ajout d’un listener Tcp sur le socket + let listener = TcpListener::bind(addr).unwrap(); - println!("En attente d’un client..."); + // création des receveurs et envoyeurs de strings asynchrones + let (sender, receiver): (Sender, Receiver) = mpsc::channel(); + let arc: Arc>> = Arc::new(RwLock::new(Vec::new())); + let arc_w = arc.clone(); - // Multi-client /////////////////////////////////////////////////////////// + // boucle infinie en parallèle pour recevoir des messages + spawn(move || { + loop { + // lit le message depuis le receveur + let msg = receiver.recv().unwrap(); + print!("DEBUG: message {}", msg); + { + let mut arc_w = arc_w.write().unwrap(); + arc_w.push(msg); + } + } + }); + + // Réception des clients for stream in listener.incoming() { - match stream { - Ok(stream) => { - let adresse = match stream.peer_addr() { - Ok(addr) => format!("[adresse : {}]", addr), - Err(_) => "inconnue".to_owned(), - }; - - let name = String::from("Toto"); - - println!("Nouveau client {}", adresse); - thread::spawn(move || handle_client(&stream, &*adresse, name)); - } - Err(e) => { - println!("La connexion du client a échoué : {}", e); + match stream { + Err(e) => println!("Erreur écoute : {}", e), + Ok(mut stream) => { + println!( + "Nouvelle connexion de {} vers {}", + stream.peer_addr().unwrap(), + stream.local_addr().unwrap() + ); + let sender = sender.clone(); + let arc = arc.clone(); + spawn(move || { + let mut stream = BufStream::new(stream); + handle_connection(&mut stream, sender, arc); + }); } } - println!("En attente d’un autre client..."); } }