328 lines
14 KiB
Java
328 lines
14 KiB
Java
import java.io.IOException;
|
|
import java.net.DatagramPacket;
|
|
import java.net.DatagramSocket;
|
|
import java.net.InetAddress;
|
|
import java.net.NetworkInterface;
|
|
import java.net.SocketException;
|
|
import java.util.ArrayList;
|
|
import java.util.Enumeration;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
import java.util.concurrent.ExecutorService;
|
|
import java.util.concurrent.Executors;
|
|
/**
|
|
* <p>
|
|
* Classe representant les echanges UDP entre utilisateurs.
|
|
* </p>
|
|
*/
|
|
|
|
public class UDPEchange {
|
|
|
|
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 ;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Méthode permettant d'envoyer un message à tout les utilisateurs
|
|
* a l'aide du protocole UDP
|
|
* </p>
|
|
* @param broadcastMessage correspond au message a transmettre aux utilisateurs
|
|
*/
|
|
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);
|
|
socket.send(packet);
|
|
socket.close();
|
|
System.out.println("Broadcast sent with address " + broadcastAddr.toString());
|
|
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("************************************");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Methode permettant la reception de messages d'utilisateurs
|
|
* a l'aide du protocole UDP
|
|
* </p>
|
|
* @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(1234);
|
|
} catch (SocketException e1) {
|
|
e1.printStackTrace();
|
|
}
|
|
byte buffer[] = new byte[1024];
|
|
System.out.println("Ecoute sur le port: 1234");
|
|
while(true)
|
|
{
|
|
DatagramPacket data = new DatagramPacket(buffer,buffer.length);
|
|
try {
|
|
socket.receive(data);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
// Un thread est lance à chaque reception d'un message
|
|
System.out.println("Message recu!");
|
|
exec.submit(new RunnerUDP(data,app));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Methode permettant d'envoyer un message a utilisateur en particulier
|
|
* a l'aide du protocole UDP
|
|
* </p>
|
|
* @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 = 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: " + Adress.toString());
|
|
System.out.println("Dest port: " + String.valueOf(1234));
|
|
System.out.println("Contenu: ");
|
|
System.out.println(Message);
|
|
System.out.println("************************************");
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Methode permettant de recuperer la liste des adresses de broadcast, chacune associer à une interface de la machine
|
|
* </p>
|
|
*/
|
|
static List<InetAddress> listAllBroadcastAddresses() throws SocketException {
|
|
List<InetAddress> broadcastList = new ArrayList<>();
|
|
Enumeration<NetworkInterface> interfaces
|
|
= NetworkInterface.getNetworkInterfaces();
|
|
while (interfaces.hasMoreElements()) {
|
|
NetworkInterface networkInterface = interfaces.nextElement();
|
|
|
|
if (networkInterface.isLoopback() || !networkInterface.isUp()) {
|
|
continue;
|
|
}
|
|
|
|
networkInterface.getInterfaceAddresses().stream()
|
|
.map(a -> a.getBroadcast())
|
|
.filter(Objects::nonNull)
|
|
.forEach(broadcastList::add);
|
|
}
|
|
return broadcastList;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* <p>
|
|
* Classe implementant l'interface Runnable.
|
|
* Contient les traitements a executer dans un thread lancer par des methodes de la class UDPEchange
|
|
* </p>
|
|
*/
|
|
class RunnerUDP implements Runnable {
|
|
final DatagramPacket data ;
|
|
ChatApp app ;
|
|
|
|
public RunnerUDP(DatagramPacket data, ChatApp app) {
|
|
this.data= data;
|
|
this.app = app ;
|
|
}
|
|
|
|
/**
|
|
* <p>
|
|
* Methode qui redefinie les traitements qui seront executes dans le thread:
|
|
* Met à jour la liste des utilisateurs actifs
|
|
* </p>
|
|
*
|
|
*/
|
|
@Override
|
|
public void run() {
|
|
System.out.println("Thread started");
|
|
String received = new String(data.getData(), 0, data.getLength());
|
|
System.out.println("***********Message recu***********");
|
|
System.out.println(received);
|
|
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");
|
|
Utilisateur u = Utilisateur.stringToUtilisateur(received.split("\n")[1]);
|
|
if (! u.equals(this.app.getMe())) { // On envoit en broadcast mais on ne souhaite pas recevoir de message de nous même
|
|
String reponse = "Reponse Connexion\n";
|
|
if (!( app.getActifUsers() ).verifierUnicite(u.getPseudo())) {
|
|
System.out.println("Pseudo deja present dans la liste");
|
|
reponse += "false\n";
|
|
}
|
|
else {
|
|
System.out.println("Ajout d'un nouvel utilisateur dans la liste des Utilisateurs");
|
|
( app.getActifUsers() ).addList(u);
|
|
reponse += "true\n";
|
|
|
|
}
|
|
reponse += app.getMe().toString();
|
|
|
|
try {
|
|
UDPEchange.envoiUnicast(u.getIp(),reponse);
|
|
}catch(IOException e)
|
|
{
|
|
System.out.println("Echec de l'envoi du message");
|
|
}
|
|
|
|
( app.getActifUsers() ).afficherListeUtilisateurs();
|
|
}
|
|
}
|
|
//*******************************************************************************************************
|
|
//*******************************************************************************************************
|
|
//****************************************Reponse d'une connexion****************************************
|
|
//*******************************************************************************************************
|
|
//*******************************************************************************************************
|
|
|
|
if (Type.equals("Reponse Connexion")) { // Un utilisateur te repond suite à ta demande de connexion
|
|
|
|
if((received.split("\n")[1]).equals("true")) {
|
|
Utilisateur u = Utilisateur.stringToUtilisateur(received.split("\n")[2]);
|
|
app.getActifUsers().addList(u);
|
|
app.getActifUsers().afficherListeUtilisateurs();
|
|
}
|
|
else {
|
|
System.out.println("Pseudo deja pris");
|
|
UDPEchange.setConnecte(false);
|
|
}
|
|
}
|
|
|
|
//*******************************************************************************************************************
|
|
//*******************************************************************************************************************
|
|
//****************************************Demande de modification d'un pseudo****************************************
|
|
//*******************************************************************************************************************
|
|
//*******************************************************************************************************************
|
|
|
|
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();
|
|
}
|
|
}
|
|
}
|
|
//************************************************************************************************************
|
|
//************************************************************************************************************
|
|
//**************************************** 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*****************************************************
|
|
//******************************************************************************************************************
|
|
//******************************************************************************************************************
|
|
|
|
if (Type.equals("Bon Choix Pseudo")) {
|
|
// 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]));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|