FEAT: Interface

This commit is contained in:
Lucàs
2022-12-05 17:54:49 +01:00
parent 75e873d44f
commit eb9d8fe6e7
11 changed files with 560 additions and 81 deletions
+68 -51
View File
@@ -2,18 +2,17 @@
<project version="4"> <project version="4">
<component name="ChangeListManager"> <component name="ChangeListManager">
<list default="true" id="79e91d13-7d5f-4b9a-954b-9bc7cde074fc" name="Changes" comment=""> <list default="true" id="79e91d13-7d5f-4b9a-954b-9bc7cde074fc" name="Changes" comment="">
<change afterPath="$PROJECT_DIR$/src/client/ListenThread.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/src/ui/FenetreClient.form" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/serveur/Server.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/src/ui/FenetreClient.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/serveur/ThreadServer.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/src/ui/FenetreErreur.java" afterDir="false" />
<change afterPath="$PROJECT_DIR$/test/utils/ResolutionDeNomTest.java" afterDir="false" /> <change afterPath="$PROJECT_DIR$/src/ui/FenetreServeur.form" afterDir="false" />
<change afterPath="$PROJECT_DIR$/src/ui/FenetreServeur.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" /> <change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/key.ser" beforeDir="false" /> <change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
<change beforePath="$PROJECT_DIR$/projet-mini-chat.iml" beforeDir="false" afterPath="$PROJECT_DIR$/projet-mini-chat.iml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/client/Client.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/client/Client.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/client/Client.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/client/Client.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/reseau/AES.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/AES.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/client/ListenThread.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/client/ListenThread.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/reseau/RSA.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/RSA.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/serveur/Server.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/server/Server.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/reseau/ResolutionDeNom.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/utils/ResolutionDeNom.java" afterDir="false" /> <change beforePath="$PROJECT_DIR$/src/serveur/ThreadServer.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/server/ThreadServer.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/src/serveur/Serveur.java" beforeDir="false" />
</list> </list>
<option name="SHOW_DIALOG" value="false" /> <option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" /> <option name="HIGHLIGHT_CONFLICTS" value="true" />
@@ -43,31 +42,32 @@
<option name="hideEmptyMiddlePackages" value="true" /> <option name="hideEmptyMiddlePackages" value="true" />
<option name="showLibraryContents" value="true" /> <option name="showLibraryContents" value="true" />
</component> </component>
<component name="PropertiesComponent"><![CDATA[{ <component name="PropertiesComponent">{
"keyToString": { &quot;keyToString&quot;: {
"Downloaded.Files.Path.Enabled": "false", &quot;Downloaded.Files.Path.Enabled&quot;: &quot;false&quot;,
"Repository.Attach.Annotations": "false", &quot;Repository.Attach.Annotations&quot;: &quot;false&quot;,
"Repository.Attach.JavaDocs": "false", &quot;Repository.Attach.JavaDocs&quot;: &quot;false&quot;,
"Repository.Attach.Sources": "false", &quot;Repository.Attach.Sources&quot;: &quot;false&quot;,
"RunOnceActivity.OpenProjectViewOnStart": "true", &quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
"RunOnceActivity.ShowReadmeOnStart": "true", &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
"WebServerToolWindowFactoryState": "false", &quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
"codeWithMe.voiceChat.enabledByDefault": "false", &quot;codeWithMe.voiceChat.enabledByDefault&quot;: &quot;false&quot;,
"com.intellij.testIntegration.createTest.CreateTestDialog.defaultLibrary": "JUnit5", &quot;com.intellij.testIntegration.createTest.CreateTestDialog.defaultLibrary&quot;: &quot;JUnit5&quot;,
"com.intellij.testIntegration.createTest.CreateTestDialog.defaultLibrarySuperClass.JUnit5": "", &quot;com.intellij.testIntegration.createTest.CreateTestDialog.defaultLibrarySuperClass.JUnit5&quot;: &quot;&quot;,
"create.test.in.the.same.root": "true", &quot;create.test.in.the.same.root&quot;: &quot;true&quot;,
"last_opened_file_path": "/Users/lucas/Documents/GitHub/projet-mini-chat/src/serveur", &quot;last_opened_file_path&quot;: &quot;/Users/lucas/Documents/GitHub/projet-mini-chat/src/serveur&quot;,
"project.structure.last.edited": "Modules", &quot;project.structure.last.edited&quot;: &quot;Modules&quot;,
"project.structure.proportion": "0.15", &quot;project.structure.proportion&quot;: &quot;0.15&quot;,
"project.structure.side.proportion": "0.2", &quot;project.structure.side.proportion&quot;: &quot;0.2&quot;,
"settings.editor.selected.configurable": "preferences.lookFeel" &quot;settings.editor.selected.configurable&quot;: &quot;preferences.lookFeel&quot;
} }
}]]></component> }</component>
<component name="RecentsManager"> <component name="RecentsManager">
<key name="CopyFile.RECENT_KEYS"> <key name="CopyFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/src/serveur" /> <recent name="$PROJECT_DIR$/src/serveur" />
</key> </key>
<key name="MoveFile.RECENT_KEYS"> <key name="MoveFile.RECENT_KEYS">
<recent name="$PROJECT_DIR$/src/ui" />
<recent name="$PROJECT_DIR$/src/client" /> <recent name="$PROJECT_DIR$/src/client" />
</key> </key>
<key name="CreateTestDialog.Recents.Supers"> <key name="CreateTestDialog.Recents.Supers">
@@ -77,20 +77,7 @@
<recent name="utils" /> <recent name="utils" />
</key> </key>
</component> </component>
<component name="RunManager" selected="Application.Client"> <component name="RunManager" selected="Application.FenetreServeur">
<configuration name="Client (1)" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="client.Client" />
<module name="projet-mini-chat" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="client.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="Client" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true"> <configuration name="Client" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="client.Client" /> <option name="MAIN_CLASS_NAME" value="client.Client" />
<module name="projet-mini-chat" /> <module name="projet-mini-chat" />
@@ -104,12 +91,12 @@
<option name="Make" enabled="true" /> <option name="Make" enabled="true" />
</method> </method>
</configuration> </configuration>
<configuration name="Client" type="Application" factoryName="Application" nameIsGenerated="true"> <configuration name="FenetreServeur" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="client.Client" /> <option name="MAIN_CLASS_NAME" value="ui.FenetreServeur" />
<module name="projet-mini-chat" /> <module name="projet-mini-chat" />
<extension name="coverage"> <extension name="coverage">
<pattern> <pattern>
<option name="PATTERN" value="client.*" /> <option name="PATTERN" value="ui.*" />
<option name="ENABLED" value="true" /> <option name="ENABLED" value="true" />
</pattern> </pattern>
</extension> </extension>
@@ -118,11 +105,37 @@
</method> </method>
</configuration> </configuration>
<configuration name="Server" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true"> <configuration name="Server" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="serveur.Server" /> <option name="MAIN_CLASS_NAME" value="server.Server" />
<module name="projet-mini-chat" /> <module name="projet-mini-chat" />
<extension name="coverage"> <extension name="coverage">
<pattern> <pattern>
<option name="PATTERN" value="serveur.*" /> <option name="PATTERN" value="server.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="ui.FenetreClient (1)" type="Application" factoryName="Application" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="ui.FenetreClient" />
<module name="projet-mini-chat" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="ui.*" />
<option name="ENABLED" value="true" />
</pattern>
</extension>
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
<configuration name="ui.FenetreClient" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
<option name="MAIN_CLASS_NAME" value="ui.FenetreClient" />
<module name="projet-mini-chat" />
<extension name="coverage">
<pattern>
<option name="PATTERN" value="ui.*" />
<option name="ENABLED" value="true" /> <option name="ENABLED" value="true" />
</pattern> </pattern>
</extension> </extension>
@@ -147,16 +160,20 @@
</method> </method>
</configuration> </configuration>
<list> <list>
<item itemvalue="Application.ui.FenetreClient (1)" />
<item itemvalue="Application.Client" /> <item itemvalue="Application.Client" />
<item itemvalue="Application.Client (1)" /> <item itemvalue="Application.FenetreServeur" />
<item itemvalue="Application.ui.FenetreClient" />
<item itemvalue="Application.Server" /> <item itemvalue="Application.Server" />
<item itemvalue="JUnit.ResolutionDeNomTest.getIPAddress" /> <item itemvalue="JUnit.ResolutionDeNomTest.getIPAddress" />
</list> </list>
<recent_temporary> <recent_temporary>
<list> <list>
<item itemvalue="Application.FenetreServeur" />
<item itemvalue="Application.ui.FenetreClient" />
<item itemvalue="Application.Client" />
<item itemvalue="Application.Server" /> <item itemvalue="Application.Server" />
<item itemvalue="Application.Client" /> <item itemvalue="Application.Client" />
<item itemvalue="JUnit.ResolutionDeNomTest.getIPAddress" />
</list> </list>
</recent_temporary> </recent_temporary>
</component> </component>
@@ -171,7 +188,7 @@
<workItem from="1668515476841" duration="6049000" /> <workItem from="1668515476841" duration="6049000" />
<workItem from="1669119772164" duration="6834000" /> <workItem from="1669119772164" duration="6834000" />
<workItem from="1669724625302" duration="6630000" /> <workItem from="1669724625302" duration="6630000" />
<workItem from="1670230395395" duration="11270000" /> <workItem from="1670230395395" duration="19588000" />
</task> </task>
<servers /> <servers />
</component> </component>
+1 -1
View File
@@ -2,7 +2,7 @@
## Avant la communication ## Avant la communication
Utiliser le RSA, avant toute communication. Utiliser le RSA, avant toute communication.
Le client et le serveur génèrent 2 clés (une publique et une privées) Le client et le server génèrent 2 clés (une publique et une privées)
Ils s'échangent leurs clé publiques. Ils s'échangent leurs clé publiques.
![img](https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Asymmetric_cryptography_-_step_1.svg/800px-Asymmetric_cryptography_-_step_1.svg.png) ![img](https://upload.wikimedia.org/wikipedia/commons/thumb/0/01/Asymmetric_cryptography_-_step_1.svg/800px-Asymmetric_cryptography_-_step_1.svg.png)
+60 -21
View File
@@ -1,8 +1,11 @@
package client; package client;
import ui.FenetreClient;
import ui.FenetreErreur;
import utils.RSA; import utils.RSA;
import utils.ResolutionDeNom; import utils.ResolutionDeNom;
import javax.swing.*;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream; import java.io.ObjectInputStream;
@@ -11,56 +14,90 @@ import java.net.ConnectException;
import java.net.Socket; import java.net.Socket;
import java.security.KeyPair; import java.security.KeyPair;
import java.security.PublicKey; import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Objects; import java.util.Objects;
import java.util.Scanner; import java.util.Scanner;
public class Client { public class Client extends Thread{
private final String SERVER_IP; private final String SERVER_IP;
private final int SERVER_PORT; private final int SERVER_PORT;
private final FenetreClient fenetre;
private String pseudo;
private final Scanner scanner; private final Scanner scanner;
private ObjectInputStream inputStream;
private ObjectOutputStream outputStream;
private KeyPair clientKeys; private KeyPair clientKeys;
private PublicKey serverKey; private PublicKey serverKey;
private String pseudo; private ObjectInputStream inputStream;
private ObjectOutputStream outputStream;
public Client(String ip, int port) { private ArrayList<String> fileAttenteMessage;
public Client(String ip, int port, String pseudo) {
this.SERVER_IP = ResolutionDeNom.getIPAddress(ip); this.SERVER_IP = ResolutionDeNom.getIPAddress(ip);
this.SERVER_PORT = port; this.SERVER_PORT = port;
this.pseudo = pseudo;
this.fenetre = null;
this.scanner = new Scanner(System.in); this.scanner = new Scanner(System.in);
this.clientKeys = RSA.genererCle(); this.clientKeys = RSA.genererCle();
this.fileAttenteMessage = new ArrayList<>();
} }
public void start() { public Client(String ip, int port, String pseudo, FenetreClient fenetre) {
System.out.print("Saisir un pseudo: "); this.SERVER_IP = ResolutionDeNom.getIPAddress(ip);
pseudo = scanner.nextLine(); this.SERVER_PORT = port;
this.pseudo = pseudo;
this.fenetre = fenetre;
this.scanner = new Scanner(System.in);
this.clientKeys = RSA.genererCle();
this.fileAttenteMessage = new ArrayList<>();
}
@Override
public void run() {
if (pseudo == null) {
System.out.print("Pseudo: ");
pseudo = scanner.nextLine();
}
try (Socket socket = new Socket(SERVER_IP, SERVER_PORT)) { try (Socket socket = new Socket(SERVER_IP, SERVER_PORT)) {
inputStream = new ObjectInputStream(socket.getInputStream()); inputStream = new ObjectInputStream(socket.getInputStream());
outputStream = new ObjectOutputStream(socket.getOutputStream()); outputStream = new ObjectOutputStream(socket.getOutputStream());
exchangeKeys(); exchangeKeys();
sendMessage(pseudo); sendMessage(pseudo);
// Ecoute du serveur // Ecoute du serveur
ListenThread threadClient = new ListenThread(this); ListenThread threadClient = new ListenThread(this, fenetre);
threadClient.start(); threadClient.start();
// Ecoute de l'entrée du clavier // Ecoute de l'entrée du clavier
System.out.println("Tappez 'bye' pour quitter\n"); System.out.println("Tapez 'bye' pour quitter\n");
String message; String message = "";
do { do {
message = scanner.nextLine(); if (fileAttenteMessage.size() > 0) {
sendMessage(message); message = fileAttenteMessage.remove(0);
sendMessage(message);
}
} while (!Objects.equals(message, "bye")); } while (!Objects.equals(message, "bye"));
} catch (ConnectException e) { } catch (ConnectException e) {
System.err.println("Serveur non trouvé"); System.err.println("Serveur non trouvé"); // TODO throw error
}catch (EOFException e) { if (fenetre != null) {
System.err.println("Connexion perdue"); new FenetreErreur("Serveur non trouvé", fenetre);
fenetre.deconnexion();
}
} catch (EOFException e) {
System.err.println("Connexion perdue"); // TODO throw error
if (fenetre != null) {
new FenetreErreur("Connexion perdue", fenetre);
fenetre.deconnexion();
}
} catch (IOException | ClassNotFoundException e) { } catch (IOException | ClassNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -84,9 +121,11 @@ public class Client {
return RSA.decrypter(messageCrypte, clientKeys.getPrivate()); return RSA.decrypter(messageCrypte, clientKeys.getPrivate());
} }
/**
public static void main(String[] args) { * Ajoute un message à la file d'attente
Client client = new Client("localhost", 4444); * @param message
client.start(); */
public void addMessage(String message) {
this.fileAttenteMessage.add(message);
} }
} }
+17
View File
@@ -1,5 +1,8 @@
package client; package client;
import ui.FenetreClient;
import ui.FenetreErreur;
import java.io.EOFException; import java.io.EOFException;
import java.io.IOException; import java.io.IOException;
import java.net.SocketException; import java.net.SocketException;
@@ -10,9 +13,16 @@ import java.net.SocketException;
public class ListenThread extends Thread { public class ListenThread extends Thread {
private final Client client; private final Client client;
private final FenetreClient fenetre;
public ListenThread(Client client) { public ListenThread(Client client) {
this.client = client; this.client = client;
this.fenetre = null;
}
public ListenThread(Client client, FenetreClient fenetre) {
this.client = client;
this.fenetre = fenetre;
} }
@Override @Override
@@ -23,11 +33,18 @@ public class ListenThread extends Thread {
while (true) { while (true) {
message = client.getMessage(); message = client.getMessage();
System.out.println(message); System.out.println(message);
if (fenetre != null) {
fenetre.displayNewMessage(message);
}
} }
} catch (SocketException ignored) { } catch (SocketException ignored) {
System.out.println("Vous avez quitté le salon"); System.out.println("Vous avez quitté le salon");
} catch (EOFException ignored) { } catch (EOFException ignored) {
System.err.println("Connexion perdue"); System.err.println("Connexion perdue");
if (fenetre != null) {
new FenetreErreur("Connexion perdue", fenetre);
fenetre.deconnexion();
}
}catch (IOException | ClassNotFoundException e) { }catch (IOException | ClassNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -1,27 +1,45 @@
package serveur; package server;
import ui.FenetreServeur;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.util.ArrayList; import java.util.ArrayList;
public class Server { public class Server extends Thread{
private final int PORT; private final int PORT;
private final ArrayList<ThreadServer> threads; private final ArrayList<ThreadServer> threads;
private final FenetreServeur fenetre;
public Server(int port) { public Server(int port) {
this.PORT = port; this.PORT = port;
this.threads = new ArrayList<>(); this.threads = new ArrayList<>();
this.fenetre = null;
} }
public void start() { public Server(int port, FenetreServeur fenetre) {
this.PORT = port;
this.fenetre = fenetre;
this.threads = new ArrayList<>();
}
@Override
public void run() {
try (ServerSocket serversocket = new ServerSocket(PORT)) { try (ServerSocket serversocket = new ServerSocket(PORT)) {
System.out.println("Server is started..."); String msg = "Serveur démarré !";
System.out.println(msg);
fenetre.displayNewMessage(msg);
while (true) { while (true) {
Socket socket = serversocket.accept(); Socket socket = serversocket.accept();
System.out.printf("Nouvelle connexion : %s\n", socket);
ThreadServer thread = new ThreadServer(socket, threads); String connexionMessage = String.format("Nouvelle connexion : %s\n", socket);
System.out.printf(connexionMessage);
fenetre.displayNewMessage(connexionMessage);
ThreadServer thread = new ThreadServer(socket, threads, fenetre);
threads.add(thread); threads.add(thread);
thread.start(); thread.start();
@@ -1,5 +1,6 @@
package serveur; package server;
import ui.FenetreServeur;
import utils.RSA; import utils.RSA;
import java.io.*; import java.io.*;
@@ -16,11 +17,22 @@ public class ThreadServer extends Thread {
private final ObjectInputStream inputStream; private final ObjectInputStream inputStream;
private final ObjectOutputStream outputStream; private final ObjectOutputStream outputStream;
private final KeyPair serverKeys; private final KeyPair serverKeys;
private final FenetreServeur fenetre;
private PublicKey clientKey; private PublicKey clientKey;
private String clientPseudo; private String clientPseudo;
public ThreadServer(Socket socket, ArrayList<ThreadServer> threads) throws IOException { public ThreadServer(Socket socket, ArrayList<ThreadServer> threads) throws IOException {
this.threads = threads; this.threads = threads;
this.fenetre = null;
this.outputStream = new ObjectOutputStream(socket.getOutputStream());
this.inputStream = new ObjectInputStream(socket.getInputStream());
this.serverKeys = RSA.genererCle();
}
public ThreadServer(Socket socket, ArrayList<ThreadServer> threads, FenetreServeur fenetre) throws IOException {
this.threads = threads;
this.fenetre = fenetre;
this.outputStream = new ObjectOutputStream(socket.getOutputStream()); this.outputStream = new ObjectOutputStream(socket.getOutputStream());
this.inputStream = new ObjectInputStream(socket.getInputStream()); this.inputStream = new ObjectInputStream(socket.getInputStream());
@@ -43,6 +55,8 @@ public class ThreadServer extends Thread {
sendMessageToEveryone(reply, true); sendMessageToEveryone(reply, true);
} while (!Objects.equals(message, "bye")); } while (!Objects.equals(message, "bye"));
} catch (EOFException e) {
System.out.printf("%s c'est déconnecté\n", clientPseudo);
} catch (IOException | ClassNotFoundException e) { } catch (IOException | ClassNotFoundException e) {
e.printStackTrace(); e.printStackTrace();
} finally { } finally {
@@ -53,6 +67,7 @@ public class ThreadServer extends Thread {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }
public void exchangeKeys() throws IOException, ClassNotFoundException { public void exchangeKeys() throws IOException, ClassNotFoundException {
@@ -63,7 +78,7 @@ public class ThreadServer extends Thread {
outputStream.writeObject(serverKeys.getPublic()); outputStream.writeObject(serverKeys.getPublic());
} }
public String getMessage() throws IOException, ClassNotFoundException { public String getMessage() throws EOFException, IOException, ClassNotFoundException {
byte[] messageCrypte = (byte[]) inputStream.readObject(); byte[] messageCrypte = (byte[]) inputStream.readObject();
return RSA.decrypter(messageCrypte, serverKeys.getPrivate()); return RSA.decrypter(messageCrypte, serverKeys.getPrivate());
} }
@@ -72,6 +87,7 @@ public class ThreadServer extends Thread {
byte[] messageCrypte = RSA.encrypter(message, clientKey); byte[] messageCrypte = RSA.encrypter(message, clientKey);
outputStream.writeObject(messageCrypte); outputStream.writeObject(messageCrypte);
if (log) System.out.println(message); if (log) System.out.println(message);
if (log && fenetre != null) {fenetre.displayNewMessage(message);}
} }
public void sendMessageToEveryone(String message, boolean log) throws IOException { public void sendMessageToEveryone(String message, boolean log) throws IOException {
@@ -79,5 +95,6 @@ public class ThreadServer extends Thread {
thread.sendMessage(message, false); thread.sendMessage(message, false);
} }
if (log) System.out.println(message); if (log) System.out.println(message);
if (log && fenetre != null) {fenetre.displayNewMessage(message);}
} }
} }
+132
View File
@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="ui.FenetreClient">
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<grid id="af8da" layout-manager="GridLayoutManager" row-count="3" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="8f6a0" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Adresse"/>
</properties>
</component>
<component id="979dd" class="javax.swing.JTextField" binding="addressInput">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<text value="localhost"/>
</properties>
</component>
<component id="3866c" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Port"/>
</properties>
</component>
<component id="d4bf0" class="javax.swing.JTextField" binding="portInput">
<constraints>
<grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<text value="4444"/>
</properties>
</component>
<component id="da4ff" class="javax.swing.JLabel">
<constraints>
<grid row="1" column="0" row-span="2" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Pseudo"/>
</properties>
</component>
<component id="e0303" class="javax.swing.JTextField" binding="pseudoInput">
<constraints>
<grid row="1" column="1" row-span="2" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<text value=""/>
</properties>
</component>
<component id="99a04" class="javax.swing.JButton" binding="connexionButton" default-binding="true">
<constraints>
<grid row="1" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Connexion"/>
</properties>
</component>
<component id="6a7bf" class="javax.swing.JButton" binding="deconnexionButton" default-binding="true">
<constraints>
<grid row="2" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Deconnexion"/>
</properties>
</component>
</children>
</grid>
<grid id="e6a97" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="6ebb0" class="javax.swing.JTextField" binding="messageInput">
<constraints>
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties/>
</component>
<component id="5a09a" class="javax.swing.JButton" binding="envoyerButton" default-binding="true">
<constraints>
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Envoyer"/>
</properties>
</component>
<scrollpane id="dd73a" binding="scrollPane">
<constraints>
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="adc9b" class="javax.swing.JTextArea" binding="chatArea">
<constraints/>
<properties/>
</component>
</children>
</scrollpane>
</children>
</grid>
</children>
</grid>
</form>
+123
View File
@@ -0,0 +1,123 @@
package ui;
import client.Client;
import javax.swing.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.util.Objects;
public class FenetreClient extends JFrame {
private JTextField addressInput, portInput, pseudoInput, messageInput;
private JButton connexionButton, envoyerButton, deconnexionButton;
private JPanel mainPanel;
private JTextArea chatArea;
private JScrollPane scrollPane;
private Client client;
public FenetreClient() {
super("Fenêtre client");
add(mainPanel);
// On ne peut pas saisir dans la boîte de dialogue directement
chatArea.setEnabled(false);
// Au lancement, on ne peut pas envoyer de message sans être connecté au serveur
messageInput.setEnabled(false);
envoyerButton.setEnabled(false);
// Action des boutons
messageInput.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) envoyerMessage();
}
});
connexionButton.addActionListener(e -> connexion());
envoyerButton.addActionListener(e -> envoyerMessage());
deconnexionButton.addActionListener(e -> deconnexion());
// Quand on clique sur fermer la fenêtre, on ferme la connexion
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {deconnexion();}
});
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400, 250);
this.setVisible(true);
}
private void envoyerMessage() {
{
String message = this.messageInput.getText();
try {
if (Objects.equals(message, "bye")) deconnexion();
else this.client.sendMessage(message);
this.messageInput.setText("");
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
}
public void connexion() {
String address = addressInput.getText();
int port = Integer.parseInt(portInput.getText());
String pseudo = pseudoInput.getText();
if (Objects.equals(pseudo.strip(), "")) {
new FenetreErreur("Pseudo vide !", this);
this.pseudoInput.setText("");
return;
}
this.client = new Client(address, port, pseudo, this);
this.client.start();
addressInput.setEnabled(false);
portInput.setEnabled(false);
pseudoInput.setEnabled(false);
messageInput.setEnabled(true);
envoyerButton.setEnabled(true);
}
public void deconnexion() {
if (client == null) return;
// Déconnecte le client
this.client.addMessage("bye");
this.client = null;
// Vide le chat
this.chatArea.setText("");
// Active les boutons pour changer de serveur
addressInput.setEnabled(true);
portInput.setEnabled(true);
pseudoInput.setEnabled(true);
// Désactive les commandes de chats
messageInput.setEnabled(false);
envoyerButton.setEnabled(false);
}
public void displayNewMessage(String message) {
// Ajoute le message
chatArea.append(message + "\n");
// Va en bas de la fenêtre
JScrollBar vertical = scrollPane.getVerticalScrollBar();
vertical.setValue(vertical.getMaximum());
}
public static void main(String[] args) {
new FenetreClient();
}
}
+15
View File
@@ -0,0 +1,15 @@
package ui;
import javax.swing.*;
public class FenetreErreur {
public FenetreErreur(String message, JFrame parent) {
final String TITLE = "Erreur";
JOptionPane.showMessageDialog(parent, message, TITLE, JOptionPane.ERROR_MESSAGE);
}
public static void main(String[] args) {
new FenetreErreur("Message", null);
}
}
+52
View File
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="ui.FenetreServeur">
<grid id="27dc6" binding="mainPanel" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
<margin top="0" left="0" bottom="0" right="0"/>
<constraints>
<xy x="20" y="20" width="500" height="400"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<scrollpane id="581b0" binding="scrollPane">
<constraints>
<grid row="1" column="0" row-span="1" col-span="3" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
</constraints>
<properties/>
<border type="none"/>
<children>
<component id="d9db2" class="javax.swing.JTextArea" binding="chatArea">
<constraints/>
<properties/>
</component>
</children>
</scrollpane>
<component id="5b8e1" class="javax.swing.JLabel">
<constraints>
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Port"/>
</properties>
</component>
<component id="a87e9" class="javax.swing.JTextField" binding="portInput">
<constraints>
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
<preferred-size width="150" height="-1"/>
</grid>
</constraints>
<properties>
<text value="4444"/>
</properties>
</component>
<component id="66d6c" class="javax.swing.JButton" binding="demarrerButton">
<constraints>
<grid row="0" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
</constraints>
<properties>
<text value="Démarrer"/>
</properties>
</component>
</children>
</grid>
</form>
+49
View File
@@ -0,0 +1,49 @@
package ui;
import server.Server;
import javax.swing.*;
public class FenetreServeur extends JFrame {
private JTextArea chatArea;
private JPanel mainPanel;
private JScrollPane scrollPane;
private JTextField portInput;
private JButton demarrerButton;
private Server server;
public FenetreServeur() {
super("Fenetre Serveur");
add(mainPanel);
chatArea.setEnabled(false);
demarrerButton.addActionListener(e -> demarrerServeur());
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400, 250);
this.setVisible(true);
}
public void demarrerServeur() {
int port = Integer.parseInt(portInput.getText());
server = new Server(port, this);
server.start();
portInput.setEnabled(false);
demarrerButton.setEnabled(false);
}
public void displayNewMessage(String message) {
// Ajoute le message
chatArea.append(message + "\n");
// Va en bas de la fenêtre
JScrollBar vertical = scrollPane.getVerticalScrollBar();
vertical.setValue(vertical.getMaximum());
}
public static void main(String[] args) {
new FenetreServeur();
}
}