TD2: Make the socket client multithreaded.
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Mon, 12 Mar 2018 14:01:42 +0000 (15:01 +0100)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Mon, 12 Mar 2018 14:01:42 +0000 (15:01 +0100)
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
TD2/Main.java
TD2/Makefile
TD2/SocketClient.java [new file with mode: 0644]
TD2/ThreadClientReceive.java [new file with mode: 0644]
TD2/ThreadClientSend.java [new file with mode: 0644]
TD2/concurrent_access.txt [new file with mode: 0644]

index 822fb58d5ad4ed2b8ebcc536918cfdf9de17263f..e7bd9638d3ce91f39700834fe09ee9679c407839 100644 (file)
@@ -3,16 +3,42 @@ import java.io.*;
 
 public class Main {
 
+       private static void main1() {
+               SocketClient client = new SocketClient();
+
+               try {
+                       client.sendMsg("Line 1 Line 2");
+                       String msg = client.receiveMsg();
+                       System.out.println(msg);
+               }
+               catch (Exception e) {
+                       System.err.println("Exception: " + e);
+               }
+               finally {
+                       client.closeRWIO();
+               }
+       }
 
-       public static void main (String[] args) {
-
-               ClientSimplifie client = new ClientSimplifie();
 
-               client.sendMsg("Line 1 Line 2");
-               String msg = client.receiveMsg();
-               System.out.println(msg);
+       public static void main (String[] args) {
 
-               client.closeRWIO();
+               try {
+                       SocketClient client = new SocketClient();
+                       ThreadClientSend thCS = new ThreadClientSend(client);
+                       thCS.setMsg("Line1 Line2");
+                       Thread thS = new Thread(thCS);
+                       Thread thR = new Thread(new ThreadClientReceive(client));
+                       thS.setName("thS");
+                       thS.start();
+                       thR.setName("thR");
+                       thR.start();
+               }
+               catch (Exception e) {
+                       System.err.println("Exception: " + e);
+               }
+               finally {
+                       client.closeRWIO();
+               }
 
        }
 
index 2ff069ebe7bd71d10f4cbfbdd8798da05b59ea08..5c0e12fce80edea360f8482d434ab6ed0f1f40dc 100644 (file)
@@ -47,6 +47,9 @@ JVM = java
 
 CLASSES = \
                ClientSimplifie.java \
+               Client.java \
+               ThreadClientSend.java \
+               ThreadClientReceive.java \
                Main.java
 
 #
diff --git a/TD2/SocketClient.java b/TD2/SocketClient.java
new file mode 100644 (file)
index 0000000..c4e74a3
--- /dev/null
@@ -0,0 +1,99 @@
+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
+    Socket sock; // le socket client
+
+    public SocketClient() {
+        // établie une connexion au serveur par un appel
+        // à connexionServeur()
+        connexionServeur("localhost", 5000);
+    }
+
+    public SocketClient(String adresseIPServeur, int portServeur) {
+        // établie une connexion au serveur par un appel
+        // à connexionServeur()
+        connexionServeur(adresseIPServeur, portServeur);
+    }
+
+    private void connexionServeur(String adresseIPServeur, int portServeur) {
+        // 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
+        try {
+            sock = new Socket(adresseIPServeur, portServeur);
+        }
+        catch (IOException e) {
+            System.err.println("IOException: " + e);
+        }
+        InputStream IStream = null;
+        try {
+            IStream = sock.getInputStream();
+        }
+        catch (IOException e) {
+            System.err.println("IOException: " + e);
+        }
+        InputStreamReader IMesg = new InputStreamReader(IStream);
+        lecture = new BufferedReader(IMesg);
+
+        OutputStream OStream = null;
+        try {
+            OStream = sock.getOutputStream();
+        }
+        catch (IOException e) {
+            System.err.println("IOException: " + e);
+        }
+        ecriture = new PrintWriter(OStream);
+    }
+
+    /**
+     * Send a message on the opened client socket
+     * @param msg a string containing the message to send
+     */
+    public synchronized void sendMsg(String msg) {
+        while (msg.isEmpty()) {
+            try {
+                wait();
+            }
+            catch (InterruptedException e) {
+                               System.err.println("InterruptedException: " + e);
+                       }
+        }
+        ecriture.println(msg);
+        ecriture.flush();
+        notifyAll();
+    }
+
+    /**
+     * Receive a message sent on the opened client socket
+     * @return a string containing the received message
+     */
+    public String receiveMsg() {
+        String line = new String();
+        try {
+            //FIXME: read only the line before the ending newline
+            line = lecture.readLine();
+        }
+        catch (IOException e) {
+            System.err.println("IOException: " + e);
+        }
+        return line;
+    }
+
+    /**
+     * Close all opened I/O streams attached to this object instance
+     */
+    public void closeRWIO() {
+        ecriture.close();
+        try {
+            lecture.close();
+        }
+        catch (IOException e) {
+            System.err.println("IOException: " + e);
+        }
+    }
+
+} // fin classe SocketClient
diff --git a/TD2/ThreadClientReceive.java b/TD2/ThreadClientReceive.java
new file mode 100644 (file)
index 0000000..7cdb21a
--- /dev/null
@@ -0,0 +1,38 @@
+import java.util.concurrent.ThreadLocalRandom;
+
+public class ThreadClientReceive implements Runnable {
+    private SocketClient client;
+    private String msg = new String();
+
+    ThreadClientReceive(SocketClient c) {
+        client = c;
+    }
+
+    /**
+     * @return the msg
+     */
+    public String getMsg() {
+       return msg;
+    }
+
+    public void run() {
+        while (true) {
+            try {
+                msg = client.receiveMsg();
+                System.out.println (Thread.currentThread().getName() + " a recu " + msg);
+                try {
+                               Thread.sleep(ThreadLocalRandom.current().nextInt(101));
+                       }
+                       catch (InterruptedException e) {
+                               System.err.println("InterruptedException: " + e);
+                       }
+            }
+            catch (Exception e) {
+                System.err.println("Exception: " + e);
+            }
+            //finally {
+            //    client.closeRWIO();
+            //}
+        }
+    }
+}
diff --git a/TD2/ThreadClientSend.java b/TD2/ThreadClientSend.java
new file mode 100644 (file)
index 0000000..2ad2bcb
--- /dev/null
@@ -0,0 +1,39 @@
+import java.util.concurrent.ThreadLocalRandom;
+
+public class ThreadClientSend implements Runnable {
+    private SocketClient client;
+    private String msg = new String();
+
+    ThreadClientSend(SocketClient c) {
+        client = c;
+    }
+
+    /**
+     * [setMsg description]
+     * @param m [description]
+     */
+    public void setMsg(String m) {
+        msg = m;
+    }
+
+    public void run() {
+        while (true) {
+            try {
+                client.sendMsg(msg);
+                System.out.println (Thread.currentThread().getName() + " a envoye " + msg);
+                try {
+                               Thread.sleep(ThreadLocalRandom.current().nextInt(101));
+                       }
+                       catch (InterruptedException e) {
+                               System.err.println("InterruptedException: " + e);
+                       }
+            }
+            catch (Exception e) {
+                System.err.println("Exception: " + e);
+            }
+            //finally {
+            //    client.closeRWIO();
+            //}
+        }
+    }
+}
diff --git a/TD2/concurrent_access.txt b/TD2/concurrent_access.txt
new file mode 100644 (file)
index 0000000..377bcdc
--- /dev/null
@@ -0,0 +1,11 @@
+Question 4:
+
+Lors d'un accès simultané au server sur le même port de deux ClientSimplifie, on
+soulève une exception sur le serveur :
+
+java.util.ConcurrentModificationException
+       at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:907)
+       at java.util.ArrayList$Itr.next(ArrayList.java:857)
+       at Serveur.afficherATous(Serveur.java:91)
+       at Serveur$GestionClient.run(Serveur.java:41)
+       at java.lang.Thread.run(Thread.java:748)