From 15850b4cdcf949dae5a150a7c209bd1b95061121 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Fri, 16 Mar 2018 11:50:20 +0100 Subject: [PATCH] TD2: Add basic IHM code for the chat. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- TD2/IHM/IHM.java | 112 +++++++++++++++++++++++++++++ TD2/IHM/LectureChaine.java | 41 +++++++++++ TD2/IHM/Makefile | 91 ++++++++++++++++++++++++ TD2/IHM/Message.java | 68 ++++++++++++++++++ TD2/IHM/SocketClient.java | 133 +++++++++++++++++++++++++++++++++++ TD2/client/SocketClient.java | 15 +++- TD2/server/Main.java | 4 +- 7 files changed, 459 insertions(+), 5 deletions(-) create mode 100644 TD2/IHM/IHM.java create mode 100644 TD2/IHM/LectureChaine.java create mode 100644 TD2/IHM/Makefile create mode 100644 TD2/IHM/Message.java create mode 100644 TD2/IHM/SocketClient.java diff --git a/TD2/IHM/IHM.java b/TD2/IHM/IHM.java new file mode 100644 index 0000000..a414ec6 --- /dev/null +++ b/TD2/IHM/IHM.java @@ -0,0 +1,112 @@ +import java.awt.BorderLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; + +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.ScrollPaneConstants; + +import java.io.IOException; + +/** + * Applications réparties + * TP 1 + * Chat, Sockets + * + * IHM pour l'application cliente + * + * @author Toto + * @version 1.0 + */ +public class IHM implements ActionListener { + + private JTextArea entrants; + private JTextField sortants; + private ArrayList sendMessages; + private SocketClient socketCl; + + IHM() { + sendMessages = new ArrayList(); + socketCl = new SocketClient(); + } + + public void go() { + JFrame cadre = new JFrame("Client de discussion"); + JPanel panneau = new JPanel(); + entrants = new JTextArea(15, 30); + entrants.setLineWrap(true); + entrants.setWrapStyleWord(true); + entrants.setEditable(false); + JScrollPane zoneTexte = new JScrollPane(entrants); + zoneTexte.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); + zoneTexte.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + sortants = new JTextField(24); + JButton boutonEnvoi = new JButton("Envoi"); + boutonEnvoi.addActionListener(this); + panneau.add(zoneTexte); + panneau.add(sortants); + panneau.add(boutonEnvoi); + cadre.getContentPane().add(BorderLayout.CENTER, panneau); + cadre.setSize(400, 310); + cadre.setVisible(true); + + panneau.setLayout(new BoxLayout(panneau, BoxLayout.Y_AXIS)); + cadre.pack(); + } // fin methode go + + synchronized public void actionPerformed(ActionEvent ev) { + sendMessages.add(sortants.getText()); + sortants.setText(""); + sortants.requestFocus(); + this.notify(); + } + + synchronized public void getAndSendNextMessage() { + try { + if (sendMessages.isEmpty()) + this.wait(); + } + catch (Exception e) { + System.err.println("Exception : " + e); + e.printStackTrace(); + } + String mess = (String)sendMessages.remove(0); + //System.out.println("IHM -> message a envoyer : " + mess); + socketCl.sendMsg(mess); + } + + public void writeMessage() throws IOException { + String mess = socketCl.receiveMsg(); + //System.out.println("IHM -> message a ecrire : " + mess); + entrants.append(mess + "\n"); + } + + public void close() { + socketCl.closeRWIO(); + } + + public static void main (String[] args) { + IHM client = new IHM(); + try { + client.go(); + while (true) { + client.getAndSendNextMessage(); + client.writeMessage(); + } + } + catch (IOException e) { + System.err.println("IOException : " + e); + e.printStackTrace(); + } + finally { + client.close(); + } + } + +} // fin classe SimpleClientDiscussion diff --git a/TD2/IHM/LectureChaine.java b/TD2/IHM/LectureChaine.java new file mode 100644 index 0000000..dfb0006 --- /dev/null +++ b/TD2/IHM/LectureChaine.java @@ -0,0 +1,41 @@ +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + + +/** + * Applications réparties + * TP 1 + * Chat, Sockets + * + * Classe utilitaire pour la saisie de chaine de caracteres + * au niveau du client + * + * @author Toto + * @version 1.0 + */ +public class LectureChaine { + public static String lireChaine() { + String inputLine = null; + try { + BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in)); + inputLine = buffer.readLine(); + if (inputLine.length() == 0) + return null; + } + catch (IOException e) { + System.out.println("IOException: " + e); + e.printStackTrace(); + } + return inputLine; + } + + public static void main(String[] args) { + //LectureChaine l = new LectureChaine(); + System.out.println("Entrer x"); + int x = new Integer(LectureChaine.lireChaine()) + 5; + System.out.println("Entrer y"); + String y = LectureChaine.lireChaine(); + System.out.println("echo : " + x + y); + } +} diff --git a/TD2/IHM/Makefile b/TD2/IHM/Makefile new file mode 100644 index 0000000..631ba1a --- /dev/null +++ b/TD2/IHM/Makefile @@ -0,0 +1,91 @@ +# define compiler and compiler flag variables +# define a variable for compiler flags (JFLAGS) +# define a variable for the compiler (JC) +# define a variable for the Java Virtual Machine (JVM) + +JFLAGS = -g +JC = javac +JVM = java + +# +# Clear any default targets for building .class files from .java files; we +# will provide our own target entry to do this in this makefile. +# make has a set of default targets for different suffixes (like .c.o) +# Currently, clearing the default for .java.class is not necessary since +# make does not have a definition for this target, but later versions of +# make may, so it doesn't hurt to make sure that we clear any default +# definitions for these +# + +.SUFFIXES: .java .class + + +# +# Here is our target entry for creating .class files from .java files +# This is a target entry that uses the suffix rule syntax: +# DSTS: +# rule +# DSTS (Dependency Suffix Target Suffix) +# 'TS' is the suffix of the target file, 'DS' is the suffix of the dependency +# file, and 'rule' is the rule for building a target +# '$*' is a built-in macro that gets the basename of the current target +# Remember that there must be a < tab > before the command line ('rule') +# + +.java.class: + $(JC) $(JFLAGS) $*.java + + +# +# CLASSES is a macro consisting of N words (one for each java source file) +# When a single line is too long, use \ to split lines that then will be +# considered as a single line. For example: +# NAME = Camilo \ + Juan +# is understood as +# NAME = Camilo Juan + +CLASSES = \ + Message.java \ + SocketClient.java \ + IHM.java + +# +# MAIN is a variable with the name of the file containing the main method +# + +MAIN = IHM + +# +# the default make target entry +# for this example it is the target classes + +default: classes + + +# Next line is a target dependency line +# This target entry uses Suffix Replacement within a macro: +# $(macroname:string1=string2) +# In the words in the macro named 'macroname' replace 'string1' with 'string2' +# Below we are replacing the suffix .java of all words in the macro CLASSES +# with the .class suffix +# + +classes: $(CLASSES:.java=.class) + + +# Next two lines contain a target for running the program +# Remember the tab in the second line. +# $(JMV) y $(MAIN) are replaced by their values + +run: $(MAIN).class + $(JVM) $(MAIN) + +# this line is to remove all unneeded files from +# the directory when we are finished executing(saves space) +# and "cleans up" the directory of unneeded .class files +# RM is a predefined macro in make (RM = rm -f) +# + +clean: + $(RM) *.class diff --git a/TD2/IHM/Message.java b/TD2/IHM/Message.java new file mode 100644 index 0000000..de1ac16 --- /dev/null +++ b/TD2/IHM/Message.java @@ -0,0 +1,68 @@ +import java.io.Serializable; +import java.util.Calendar; +import java.text.SimpleDateFormat; + +public class Message implements Serializable { + // L'emeteur du message + private String emetteur; + // Le contenu du message + private String texte; + // Heure du message + private Calendar heure; + private static final long serialVersionUID = 1L; + + // Les méthodes + + Message(String name, String msg, Calendar c) { + emetteur = name; + texte = msg; + heure = c; + } + + /** + * @param name the emetteur to set + */ + public void setEmetteur(String name) { + emetteur = name; + } + + /** + * @return the emetteur + */ + public String getEmetteur() { + return emetteur; + } + + /** + * @param texte the texte to set + */ + public void setTexte(String texte) { + this.texte = texte; + } + + /** + * @return the texte + */ + public String getTexte() { + return texte; + } + + /** + * @param heure the heure to set + */ + public void setHeure(Calendar heure) { + this.heure = heure; + } + + /** + * @return the heure + */ + public Calendar getHeure() { + return heure; + } + + public String toString() { + SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss"); + return "<" + emetteur + "|" + dateFormat.format(heure.getTime()) + "> " + texte; + } +} diff --git a/TD2/IHM/SocketClient.java b/TD2/IHM/SocketClient.java new file mode 100644 index 0000000..92c7412 --- /dev/null +++ b/TD2/IHM/SocketClient.java @@ -0,0 +1,133 @@ +import java.io.*; +import java.net.*; +import java.util.*; + +public class SocketClient { + BufferedReader lecture; // pour le flot d'entrée venant du serveur + PrintWriter ecriture; // pour le flot de sortie vers le serveur + ObjectInput oLecture; + ObjectOutput oEcriture; + Socket sock; // le socket client + + public SocketClient() { + // établie une connexion au serveur par un appel + // à connexionServeur() + attributesInit(); + try { + connexionServeur("localhost", 5000); + } + catch (IOException e) { + System.err.println("IOException: " + e); + e.printStackTrace(); + closeRWIO(); + } + } + + public SocketClient(String adresseIPServeur, int portServeur) { + // établie une connexion au serveur par un appel + // à connexionServeur() + attributesInit(); + try { + connexionServeur(adresseIPServeur, portServeur); + } + catch (IOException e) { + System.err.println("IOException: " + e); + e.printStackTrace(); + closeRWIO(); + } + } + + private void connexionServeur(String adresseIPServeur, int portServeur, boolean hasoStream) throws IOException { + // créer un objet socket lié au socket serveur et l'affecte à sock + // puis établie les chaînages de flot nécessaires + // pour l'envoi et la reception de messages + sock = new Socket(adresseIPServeur, portServeur); + + OutputStream OStream = sock.getOutputStream(); + ecriture = new PrintWriter(OStream); + if (hasoStream) + oEcriture = new ObjectOutputStream(OStream); + + InputStream IStream = sock.getInputStream(); + InputStreamReader IMesg = new InputStreamReader(IStream); + lecture = new BufferedReader(IMesg); + if (hasoStream) + oLecture = new ObjectInputStream(IStream); + } + + private void connexionServeur(String adresseIPServeur, int portServeur) throws IOException { + // créer un objet socket lié au socket serveur et l'affecte à sock + // puis établie les chaînages de flot nécessaires + // pour l'envoi et la reception de messages + connexionServeur(adresseIPServeur, portServeur, false); + } + + private void attributesInit() { + sock = null; + lecture = null; + ecriture = null; + oLecture = null; + oEcriture = null; + } + + /** + * Send a message on the opened client socket + * @param msg a string containing the message to send + */ + public void sendMsg(String msg) { + ecriture.println(msg); + ecriture.flush(); + } + + /** + * Send an object message on the opened client socket + * @param msg a string containing the message to send + */ + public void sendoMsg(Message oMsg) throws IOException { + oEcriture.writeObject(oMsg); + oEcriture.flush(); + } + + /** + * Receive a message sent on the opened client socket + * @return a string containing the received message + */ + public String receiveMsg() throws IOException { + String line = new String(); + //FIXME?: read only the line before the ending newline + line = lecture.readLine(); + return line; + } + + /** + * Receive an object message sent on the opened client socket + * @return a string containing the received message + */ + public Message receiveoMsg() throws IOException, ClassNotFoundException { + return (Message)oLecture.readObject(); + } + + /** + * Close all opened I/O streams attached to this object instance + */ + public void closeRWIO() { + try { + if (sock != null) + sock.close(); + if (lecture != null) + lecture.close(); + if (ecriture != null) + ecriture.close(); + if (oLecture != null) + oLecture.close(); + if (oEcriture != null) { + oEcriture.close(); + } + } + catch (IOException e) { + System.err.println("IOException: " + e); + e.printStackTrace(); + } + } + +} // fin classe SocketClient diff --git a/TD2/client/SocketClient.java b/TD2/client/SocketClient.java index 75c0470..92c7412 100644 --- a/TD2/client/SocketClient.java +++ b/TD2/client/SocketClient.java @@ -37,7 +37,7 @@ public class SocketClient { } } - private void connexionServeur(String adresseIPServeur, int portServeur) throws IOException { + private void connexionServeur(String adresseIPServeur, int portServeur, boolean hasoStream) throws IOException { // créer un objet socket lié au socket serveur et l'affecte à sock // puis établie les chaînages de flot nécessaires // pour l'envoi et la reception de messages @@ -45,12 +45,21 @@ public class SocketClient { OutputStream OStream = sock.getOutputStream(); ecriture = new PrintWriter(OStream); - oEcriture = new ObjectOutputStream(OStream); + if (hasoStream) + oEcriture = new ObjectOutputStream(OStream); InputStream IStream = sock.getInputStream(); InputStreamReader IMesg = new InputStreamReader(IStream); lecture = new BufferedReader(IMesg); - oLecture = new ObjectInputStream(IStream); + if (hasoStream) + oLecture = new ObjectInputStream(IStream); + } + + private void connexionServeur(String adresseIPServeur, int portServeur) throws IOException { + // créer un objet socket lié au socket serveur et l'affecte à sock + // puis établie les chaînages de flot nécessaires + // pour l'envoi et la reception de messages + connexionServeur(adresseIPServeur, portServeur, false); } private void attributesInit() { diff --git a/TD2/server/Main.java b/TD2/server/Main.java index 7a01138..4e3da51 100644 --- a/TD2/server/Main.java +++ b/TD2/server/Main.java @@ -9,8 +9,8 @@ public class Main { while (true) { // le dispatcher est le thread qui execute main() Socket clientSocket = listenSocket.accept(); System.out.println("Connexion de :" + clientSocket.getInetAddress()); - //Thread serviceThread = new Thread(new BroadcastThreadService(clientSocket)); - Thread serviceThread = new Thread(new BroadcastoThreadService(clientSocket)); + Thread serviceThread = new Thread(new BroadcastThreadService(clientSocket)); + //Thread serviceThread = new Thread(new BroadcastoThreadService(clientSocket)); serviceThread.start(); } } -- 2.34.1