diff --git a/Implementation/src/ChatApp.class b/Implementation/src/ChatApp.class index ebf46a2..896d42c 100644 Binary files a/Implementation/src/ChatApp.class and b/Implementation/src/ChatApp.class differ diff --git a/Implementation/src/ChatApp.java b/Implementation/src/ChatApp.java index 065ee88..e6fc6f4 100644 --- a/Implementation/src/ChatApp.java +++ b/Implementation/src/ChatApp.java @@ -16,7 +16,7 @@ import java.util.concurrent.Executors; /** *

-* Classe récapitulant toutes les actions possibles pour un utilisateur +* Classe recapitulant toutes les actions possibles pour un utilisateur *

*/ @@ -24,19 +24,11 @@ public class ChatApp { /* Liste des utilisateurs actifs */ private ListUtilisateurs actifUsers ; - private static ArrayList ListPort = new ArrayList(); + + /* Map on l'on stocke localement les historiques des messages */ private Map mapHistorique ; - - - - - - public static ArrayList getListPort() { - return ListPort; - } - - /* ChatApp est associé à un utilisateur */ + /* ChatApp est associe a un utilisateur */ private Utilisateur me; /** @@ -50,17 +42,21 @@ public class ChatApp { // Recuperer adresse IP de l'utilisateur InetAddress ip = null ; try { - //ip = InetAddress.getByName("192.168.1.72"); ip = InetAddress.getLocalHost(); } catch (UnknownHostException e) { e.printStackTrace(); } - //ip.getHostAddress(); this.me = new Utilisateur(pseudo,port,ip); this.actifUsers.addList(getMe()); this.mapHistorique = new HashMap() ; } + /** + * Mettre a jour dans Maphistorique, l'historique avec un utilisateur dont le nom est pseudo + * + * @param pseudo Pseudo de l'utilisateur + * @param h nouvel Historique entre les deux utilisateurs + */ public void majHistorique(String pseudo,Historique h) { getMapHistorique().put(h.getUser2().getPseudo(),h); } @@ -74,112 +70,100 @@ public class ChatApp { * @param nouveau correspond au nouveau pseudo */ public void modifierPseudo(String nouveau) throws IOException { - // @ de broadcast du réseau de l'utilisateur me - InetAddress broadcastAdress = InetAddress.getLoopbackAddress(); // A MODIFIER // Message que l'on envoie à tous les utilisateurs actifs - String broadcastMessage = "Modification Pseudo\n" + this.getMe().toString() + "\n" + nouveau + "\n"; - /*for(Integer p : ListPort ) { - if(!(p.equals(this.getMe().getPort()))) - { - UDPEchange.connexion(broadcastAdress,broadcastMessage, p); - } - }*/ - UDPEchange.connexion(broadcastAdress,broadcastMessage, 1234); + String broadcastMessage = "Demande Modification Pseudo\n" + this.getMe().toString() + "\n" + nouveau + "\n"; + UDPEchange.EnvoiBroadcast(broadcastMessage); + try { + Thread.sleep(1000); + /* L'utilisateur doit attendre la reponse de tous les utilisateurs connectes + * pour savoir si son pseudo est accepte + */ + } catch (InterruptedException e) { + e.printStackTrace(); + } + if (UDPEchange.getPseudoValide()) { + System.out.println("Modification pseudo reussie"); + //Envoi un msg en broadcast a tout les utilisateurs pour les prevenir de son nouveau pseudo// + broadcastMessage = "Modification pseudo reussie\n" + this.getMe().toString() + "\n" + nouveau + "\n"; + UDPEchange.EnvoiBroadcast(broadcastMessage); + //-------Change son propre nom d'utilisateur-------// + this.getActifUsers().modifierList(this.getMe().getPseudo(), nouveau); + this.getMe().setPseudo(nouveau); + System.out.println("Changement pseudo accepte, nouvelle liste des utilisateurs actifs:"); + this.getActifUsers().afficherListeUtilisateurs(); + } + else + { + System.out.println("Connexion echoue"); + System.exit(1) ; // A MODIFIER NORMALEMENT ON LUI DEMANDE DE CHOISIR UN NV MDP + } } /** - * Methode appelée lors de la connexion d'un nouvel utilisateur. - * Il va prévenir les utilisateurs du réseau de son arrivée. + * Methode appelee lors de la connexion d'un nouvel utilisateur. + * Il va prevenir les utilisateurs du reseau de son arrivee. * */ public void connexion() throws IOException { - // @ de broadcast du réseau de l'utilisateur me - InetAddress broadcastAdress = InetAddress.getLoopbackAddress(); // A MODIFIER // Message que l'on envoie à tous les utilisateurs actifs String broadcastMessage = "Connexion\n" + this.getMe().toString() ; - /*for(Integer p : ListPort ) { - if(!(p.equals(this.getMe().getPort()))) - { - UDPEchange.connexion(broadcastAdress,broadcastMessage, p); + UDPEchange.EnvoiBroadcast(broadcastMessage); + try { + Thread.sleep(1000); // L'utilisateur doit attendre la reponse de tous les utilisateurs connectes + } catch (InterruptedException e) { + e.printStackTrace(); } - }*/ - UDPEchange.connexion(broadcastAdress,broadcastMessage, 1234); + if (UDPEchange.getConnecte()) { + System.out.println("Connexion reussie"); + } + else + { + System.out.println("Connexion echoue"); + System.exit(1) ; // A MODIFIER NORMALEMENT ON LUI DEMANDE DE CHOISIR UN NV MDP + } } /** - * Methode appelée lors de la déconnexion de l'utilisateur. - * Il va prévenir les utilisateurs du réseau de son départ. + * Methode appelee lors de la deconnexion de l'utilisateur. + * Il va prevenir les utilisateurs du reseau de son depart. * */ public void deconnexion() throws IOException { - // @ de broadcast du réseau de l'utilisateur me - InetAddress broadcastAdress = InetAddress.getLoopbackAddress(); // A MODIFIER // Message que l'on envoie à tous les utilisateurs actifs String broadcastMessage = "Deconnexion\n" + this.getMe().toString() ; - /*for(Integer p : ListPort ) { - if(!(p.equals(this.getMe().getPort()))) - { - UDPEchange.connexion(broadcastAdress,broadcastMessage, p); - } - }*/ - UDPEchange.connexion(broadcastAdress,broadcastMessage, 1234); - } - - public static void main (String[] args) throws IOException { - //Integer p = 2345 ; - ChatApp app = new ChatApp(args[0],Integer.parseInt(args[1])) ; - InetAddress localHost = InetAddress.getLocalHost() ; - System.out.println("Mon adress: "+ localHost.toString()); - ListPort.add(1234); - ListPort.add(3000); - ListPort.add(4000); - /*for(InetAddress broadcastAddr : UDPEchange.listAllBroadcastAddresses()) { - System.out.println("Broadcast sent with address " + broadcastAddr.toString()); - }*/ - //InetAddress broadcastAddress = InterfaceAddress.getBroadcast(); - //System.out.println("Mon adresse:" + localHost.toString()); - ExecutorService exec = Executors.newFixedThreadPool(1000); - exec.submit(new Runner(app)); - try { - app.connexion(); - } catch (IOException e) { - e.printStackTrace(); - } - - if (app.getMe().getPort() == 4000) { - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - app.modifierPseudo("Doudou"); - try { - Thread.sleep(2000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - app.modifierPseudo("Eliot"); - /*try { - Thread.sleep(2000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - app.deconnexion(); */ - } + UDPEchange.EnvoiBroadcast(broadcastMessage); } + + /** + * Getter + * @return Utilisateur associee a ChatApp + */ public Utilisateur getMe() { return me; } - + + /** + * Getter + * @return Liste des utilisateurs actifs associee a ChatApp + */ public ListUtilisateurs getActifUsers() { return actifUsers; } - + + /** + * Getter + * @return la map des historiques + */ public Map getMapHistorique() { return mapHistorique; } + /** + * Obtenir l'historique entre deux utilisateurs + * @param pseudo Pseudo de l'utilisateur dont on souhaite obtenir l'historique + * @return Un historique + */ public Historique getHist(String pseudo) { Historique h = this.mapHistorique.get(pseudo); if( h != null) { @@ -190,9 +174,25 @@ public class ChatApp { return h ; } } - - - + + public static void main (String[] args) throws IOException { + ChatApp app = new ChatApp(args[0],Integer.parseInt(args[1])) ; + ExecutorService exec = Executors.newFixedThreadPool(1000); + exec.submit(new Runner(app)); + try { + app.connexion(); + } catch (IOException e) { + e.printStackTrace(); + } + + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + app.modifierPseudo("Jean"); + + } } diff --git a/Implementation/src/ListUtilisateurs.class b/Implementation/src/ListUtilisateurs.class index 184b669..e6a1cf6 100644 Binary files a/Implementation/src/ListUtilisateurs.class and b/Implementation/src/ListUtilisateurs.class differ diff --git a/Implementation/src/ListUtilisateurs.java b/Implementation/src/ListUtilisateurs.java index f87874c..d3fc8db 100644 --- a/Implementation/src/ListUtilisateurs.java +++ b/Implementation/src/ListUtilisateurs.java @@ -72,6 +72,10 @@ public class ListUtilisateurs { } } this.afficherListeUtilisateurs(); + } + + public Boolean appartient(Utilisateur u) { + return this.actifUsers.contains(u); } diff --git a/Implementation/src/Runner.class b/Implementation/src/Runner.class index 3f6e0cc..1eb00b8 100644 Binary files a/Implementation/src/Runner.class and b/Implementation/src/Runner.class differ diff --git a/Implementation/src/RunnerUDP.class b/Implementation/src/RunnerUDP.class index 32bddcd..1d25cd3 100644 Binary files a/Implementation/src/RunnerUDP.class and b/Implementation/src/RunnerUDP.class differ diff --git a/Implementation/src/UDPEchange.class b/Implementation/src/UDPEchange.class index 9e1c58d..80f5f66 100644 Binary files a/Implementation/src/UDPEchange.class and b/Implementation/src/UDPEchange.class differ diff --git a/Implementation/src/UDPEchange.java b/Implementation/src/UDPEchange.java index 8987408..c028b5d 100644 --- a/Implementation/src/UDPEchange.java +++ b/Implementation/src/UDPEchange.java @@ -12,93 +12,95 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** *

-* Classe representant les échanges UDP entre utilisateurs. +* Classe representant les echanges UDP entre utilisateurs. *

*/ public class UDPEchange { - private static Boolean Connecte = true; // True si l'utilisateur peut se connecter avec ce nom d'utilisateur , False sinon + private static Boolean Connecte = true; + // True si l'utilisateur peut se connecter avec ce nom d'utilisateur , False sinon + /** + * Getter + * @return le boolean connecte (True s'il peut se connecter avec ce nom d'utilisateur , False sinon) + */ public static Boolean getConnecte() { return Connecte; } + + /** + * Setter + * @param value La nouvelle valeur du boolean de connexion + */ public static void setConnecte(Boolean value) { Connecte = value ; } + private static Boolean PseudoValide = true; + // True si l'utilisateur a (ou demande) un pseudo valide , False sinon + + /** + * Getter + * @return le boolean PseudoValide (True s'il peut utiliser ce pseudo , False sinon) + */ + public static Boolean getPseudoValide() { + return PseudoValide; + } + + /** + * Setter + * @param value La nouvelle valeur du boolean concernant le pseudo valide + */ + public static void setPseudoValide(Boolean value) { + PseudoValide = value ; + } + /** *

* Méthode permettant d'envoyer un message à tout les utilisateurs - * à l'aide du protocole UDP + * a l'aide du protocole UDP *

- * - * @param broadcastAdress l'addresse de broadcast du réseau - * @param broadcastMessage correspond au message à transmettre aux utilisateurs - * @param port : port destination - * + * @param broadcastMessage correspond au message a transmettre aux utilisateurs */ - public static void connexion( InetAddress broadcastAdress , String broadcastMessage , Integer port) throws IOException { + public static void EnvoiBroadcast(String broadcastMessage) throws IOException { + int port = 1234 ; // Envoie en broadcast à tous les utilsateurs for (InetAddress broadcastAddr : listAllBroadcastAddresses()) { DatagramSocket socket = new DatagramSocket(); socket.setBroadcast(true); byte[]buffer = broadcastMessage.getBytes(); - DatagramPacket packet = new DatagramPacket( buffer, buffer.length, broadcastAddr, port ); + DatagramPacket packet = new DatagramPacket( buffer, buffer.length, broadcastAddr,port); socket.send(packet); socket.close(); System.out.println("Broadcast sent with address " + broadcastAddr.toString()); - try { - Thread.sleep(1000); // L'utilisateur doit attendre la réponse de tous les utilisateurs connectes - } catch (InterruptedException e) { - e.printStackTrace(); - } - if (UDPEchange.getConnecte()) { - System.out.println("Connexion reussie"); - } - else - { - System.out.println("Connexion echoue"); - System.exit(1) ; // A MODIFIER NORMALEMENT ON LUI DEMANDE DE CHOISIR UN NV MDP - } + System.out.println("***********Message envoye***********"); + System.out.println("Dest Ip: " + broadcastAddr.toString()); + System.out.println("Dest port: " + String.valueOf(port)); + System.out.println("Contenu: "); + System.out.println(broadcastMessage); + System.out.println("************************************"); } - /* - DatagramSocket socket = new DatagramSocket(); - socket.setBroadcast(true); - byte[]buffer = broadcastMessage.getBytes(); - DatagramPacket packet = new DatagramPacket( buffer, buffer.length, broadcastAdress, port ); - socket.send(packet); - socket.close(); - */ - - System.out.println("***********Message envoye***********"); - System.out.println("Dest Ip: " + broadcastAdress.toString()); - System.out.println("Dest port: " + port.toString()); - System.out.println("Contenu: "); - System.out.println(broadcastMessage); - System.out.println("************************************"); } /** *

- * Méthode permettant la reception de messages d'utilisateurs - * à l'aide du protocole UDP + * Methode permettant la reception de messages d'utilisateurs + * a l'aide du protocole UDP *

- * * @param app L'application de chat de l'utilisateur qui receptionne le message - * */ public static void ecouteUDP(ChatApp app) { DatagramSocket socket = null; ExecutorService exec = Executors.newFixedThreadPool(1000); try { - socket = new DatagramSocket(app.getMe().getPort()); + socket = new DatagramSocket(1234); } catch (SocketException e1) { e1.printStackTrace(); } byte buffer[] = new byte[1024]; - System.out.println("Ecoute sur le port: "+app.getMe().getPort().toString()); + System.out.println("Ecoute sur le port: 1234"); while(true) { DatagramPacket data = new DatagramPacket(buffer,buffer.length); @@ -107,29 +109,39 @@ public class UDPEchange { } catch (IOException e) { e.printStackTrace(); } - // Un thread est lancé à chaque reception d'un message + // Un thread est lance à chaque reception d'un message System.out.println("Message recu!"); exec.submit(new RunnerUDP(data,app)); } } - public static void envoiUnicast( InetAddress broadcastAdress , String broadcastMessage , Integer port) throws IOException { - // Envoie en broadcast à tous les utilsateurs + /** + *

+ * Methode permettant d'envoyer un message a utilisateur en particulier + * a l'aide du protocole UDP + *

+ * @param Adress l'addresse de l'utilisateur + * @param Message correspond au message à transmettre a l'utilisateur + */ + public static void envoiUnicast( InetAddress Adress , String Message ) throws IOException { DatagramSocket socket = new DatagramSocket(); - byte[]buffer = broadcastMessage.getBytes(); - //DatagramPacket packet = new DatagramPacket( buffer, buffer.length, InetAddress.getLoopbackAddress(), port ); - DatagramPacket packet = new DatagramPacket( buffer, buffer.length, broadcastAdress, port ); + byte[]buffer = Message.getBytes(); + DatagramPacket packet = new DatagramPacket( buffer, buffer.length, Adress, 1234 ); socket.send(packet); socket.close(); System.out.println("***********Message envoye***********"); - System.out.println("Dest Ip: " + broadcastAdress.toString()); - System.out.println("Dest port: " + port.toString()); + System.out.println("Dest Ip: " + Adress.toString()); + System.out.println("Dest port: " + String.valueOf(1234)); System.out.println("Contenu: "); - System.out.println(broadcastMessage); + System.out.println(Message); System.out.println("************************************"); } - + /** + *

+ * Methode permettant de recuperer la liste des adresses de broadcast, chacune associer à une interface de la machine + *

+ */ static List listAllBroadcastAddresses() throws SocketException { List broadcastList = new ArrayList<>(); Enumeration interfaces @@ -155,8 +167,8 @@ public class UDPEchange { /** *

-* Classe implémentant l'interface Runnable. -* Contient les traitements à executer dans un thread lancer par des méthodes de la class UDPEchange +* Classe implementant l'interface Runnable. +* Contient les traitements a executer dans un thread lancer par des methodes de la class UDPEchange *

*/ class RunnerUDP implements Runnable { @@ -170,7 +182,7 @@ class RunnerUDP implements Runnable { /** *

- * Méthode qui redefinie les traitements qui seront exécutés dans le thread: + * Methode qui redefinie les traitements qui seront executes dans le thread: * Met à jour la liste des utilisateurs actifs *

* @@ -184,10 +196,10 @@ class RunnerUDP implements Runnable { System.out.println("**********************************"); String Type = received.split("\n")[0]; - //************************************************************************************************************************ - //************************************************************************************************************************* + //**************************************************************************************************** + //**************************************************************************************************** //****************************************Demande de connexion**************************************** - //************************************************************************************************************************ + //**************************************************************************************************** //**************************************** if (Type.equals("Connexion")) { // un utilisateur vient d'arriver sur le reseau System.out.println("Reception d'une demande de connexion"); @@ -207,7 +219,7 @@ class RunnerUDP implements Runnable { reponse += app.getMe().toString(); try { - UDPEchange.envoiUnicast(u.getIp(),reponse,u.getPort()); + UDPEchange.envoiUnicast(u.getIp(),reponse); }catch(IOException e) { System.out.println("Echec de l'envoi du message"); @@ -216,11 +228,11 @@ class RunnerUDP implements Runnable { ( app.getActifUsers() ).afficherListeUtilisateurs(); } } - //************************************************************************************************************************ - //************************************************************************************************************************* + //******************************************************************************************************* + //******************************************************************************************************* //****************************************Reponse d'une connexion**************************************** - //************************************************************************************************************************ - //************************************************************************************************************************ + //******************************************************************************************************* + //******************************************************************************************************* if (Type.equals("Reponse Connexion")) { // Un utilisateur te repond suite à ta demande de connexion @@ -235,71 +247,75 @@ class RunnerUDP implements Runnable { } } - //************************************************************************************************************************ - //************************************************************************************************************************* + //******************************************************************************************************************* + //******************************************************************************************************************* //****************************************Demande de modification d'un pseudo**************************************** - //************************************************************************************************************************ - //************************************************************************************************************************ + //******************************************************************************************************************* + //******************************************************************************************************************* - if (Type.equals("Modification Pseudo")) { - if(( app.getActifUsers() ).verifierUnicite(received.split("\n")[2])) { - ( app.getActifUsers() ).modifierList(received.split("\n")[1],received.split("\n")[2]); - Utilisateur Destination = Utilisateur.stringToUtilisateur(received.split("\n")[1]); - String Message = "Bon Choix Pseudo\n" + received.split("\n")[2] ; - System.out.println(Message); - try { - - //UDPEchange.envoiUnicast(Destination.getIp(),Message, Destination.getPort()); - UDPEchange.envoiUnicast(InetAddress.getLoopbackAddress(),Message, 4000); - } catch (IOException e) { - e.printStackTrace(); - } - } - else { - Utilisateur Destination = ( app.getActifUsers() ).getPseudoList(received.split("\n")[1]); - String Message = "Mauvais Choix Pseudo\n" ; - System.out.println(Message); - try { - UDPEchange.envoiUnicast(Destination.getIp(),Message, Destination.getPort()); - } catch (IOException e) { - e.printStackTrace(); - } - } - ( app.getActifUsers() ).afficherListeUtilisateurs(); + if (Type.equals("Demande Modification Pseudo")) { + Utilisateur Source = Utilisateur.stringToUtilisateur(received.split("\n")[1]); + if (! Source.equals(this.app.getMe())) { // On envoit en broadcast mais on ne souhaite pas recevoir de message de nous même + String nouveau = received.split("\n")[2] ; + String Message = ""; + if(( app.getActifUsers() ).verifierUnicite(nouveau)) { + Message = "Bon Choix Pseudo\n" + nouveau ; + } + else { + Message = "Mauvais Choix Pseudo\n" ; + } + System.out.println(Message); + try { + UDPEchange.envoiUnicast(Source.getIp(),Message); + } catch (IOException e) { + e.printStackTrace(); + } + } } - //************************************************************************************************************************ - //************************************************************************************************************************* - //****************************************Mauvais choix d'un pseudo**************************************** - //************************************************************************************************************************ - //**************************************** + //************************************************************************************************************ + //************************************************************************************************************ + //**************************************** Modification pseudo reussi **************************************** + //************************************************************************************************************ + //************************************************************************************************************ - + if (Type.equals("Modification pseudo reussi")) { + Utilisateur Source = Utilisateur.stringToUtilisateur(received.split("\n")[1]); + if (! Source.equals(this.app.getMe())) { // On envoit en broadcast mais on ne souhaite pas recevoir de message de nous même + String nouveau = received.split("\n")[2] ; + if(app.getActifUsers().appartient(Source)) { // On verifie d'abord que Source appartient bien a la liste des utilisateurs actifs + app.getActifUsers().modifierList(Source.getPseudo(), nouveau); + } + { + // Suite a une perte d'un message lors d'une connexion l'utilisateur Source n'apparait pas dans la liste + app.getActifUsers().addList(Source); + } + } + } + //********************************************************************************************************* + //********************************************************************************************************* + //****************************************Mauvais choix d'un pseudo**************************************** + //********************************************************************************************************* + //********************************************************************************************************* if (Type.equals("Mauvais Choix Pseudo")) { System.out.println("Ce choix de pseudo est déjà pris il te faut en choisir un autre"); + UDPEchange.setPseudoValide(false); } - //************************************************************************************************************************ - //************************************************************************************************************************* - //****************************************Bon choix d'un pseudo**************************************** - //************************************************************************************************************************ - //************************************************************************************************************************ + //****************************************************************************************************************** + //****************************************************************************************************************** + //****************************************Bon choix d'un pseudo***************************************************** + //****************************************************************************************************************** + //****************************************************************************************************************** if (Type.equals("Bon Choix Pseudo")) { - - ( app.getActifUsers() ).supprimerList(app.getMe()); - - app.getMe().setPseudo(received.split("\n")[1]); - - ( app.getActifUsers() ).addList(app.getMe()); - System.out.println("Changement pseudo accepte, nouvelle liste des utilisateurs actifs:"); - app.getActifUsers().afficherListeUtilisateurs(); + // Il n'y a rien a faire ici } - //************************************************************************************************************************ - //************************************************************************************************************************* + //********************************************************************************************************* + //********************************************************************************************************* //****************************************Demande d'une deconnexion**************************************** - //************************************************************************************************************************ - //************************************************************************************************************************ + //********************************************************************************************************* + //********************************************************************************************************* if (Type.equals("Deconnexion")) { ( app.getActifUsers() ).supprimerList(Utilisateur.stringToUtilisateur(received.split("\n")[1])); diff --git a/Implementation/src/Utilisateur.class b/Implementation/src/Utilisateur.class index 2c23d5d..b3f5fb2 100644 Binary files a/Implementation/src/Utilisateur.class and b/Implementation/src/Utilisateur.class differ