From 869288ce42b8ba98d5e68f148c04a631554bffd0 Mon Sep 17 00:00:00 2001
From: CapitainMorgan <40363984+CapitainMorgan@users.noreply.github.com>
Date: Fri, 19 Mar 2021 14:22:02 +0100
Subject: [PATCH 1/7] add my specs
---
specs/CapitainMorgan/PROTOCOL.md | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
create mode 100644 specs/CapitainMorgan/PROTOCOL.md
diff --git a/specs/CapitainMorgan/PROTOCOL.md b/specs/CapitainMorgan/PROTOCOL.md
new file mode 100644
index 0000000..36704e2
--- /dev/null
+++ b/specs/CapitainMorgan/PROTOCOL.md
@@ -0,0 +1,27 @@
+> What transport protocol do we use?
+
+TCP
+
+> How does the client find the server (addresses and ports)?
+
+IDK
+
+> Who speaks first?
+
+Client
+
+> What is the sequence of messages exchanged by the client and the server? (flow)
+
+Client -> mult 5 2 -> serveur -> 10 -> Client
+
+> What happens when a message is received from the other party? (semantics)
+
+IDK
+
+> What is the syntax of the messages? How we generate and parse them? (syntax)
+
+add 5 2,minus 5 2, mult 5 2, div 5 2,
+
+> Who closes the connection and when?
+
+serveur après 2min
\ No newline at end of file
From eb3df2ba65dc8ff4fe4482728df51b892b13e8cb Mon Sep 17 00:00:00 2001
From: issolahma <22448610+issolahma@users.noreply.github.com>
Date: Fri, 19 Mar 2021 14:24:38 +0100
Subject: [PATCH 2/7] add protocol spec
---
specs/issolahma/protocol.md | 57 +++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
create mode 100644 specs/issolahma/protocol.md
diff --git a/specs/issolahma/protocol.md b/specs/issolahma/protocol.md
new file mode 100644
index 0000000..0eb35c9
--- /dev/null
+++ b/specs/issolahma/protocol.md
@@ -0,0 +1,57 @@
+ * What transport protocol do we use?
+
+ TCP
+
+
+
+ * How does the client find the server (addresses and ports)?
+
+ IP:2828
+
+
+
+ * Who speaks first?
+
+ client
+
+
+
+ * What is the sequence of messages exchanged by the client and the server? (flow)
+
+ client -> askconn -> server
+
+ server -> connOk -> client
+
+ client -> operation -> server
+
+ server -> result/error -> client
+
+
+
+ * What happens when a message is received from the other party? (semantics)
+
+ - check the message
+
+ - respond to the message
+
+
+
+ * What is the syntax of the messages? How we generate and parse them? (syntax)
+
+ add num num
+
+ mult num num
+
+ askConn
+
+ connOk
+
+ connErr
+
+ syntaxError
+
+
+
+ * Who closes the connection and when?
+
+ server after 2min no msg
\ No newline at end of file
From 7ad7d548c2d4545e601c58b5eba1026d2be2ec4b Mon Sep 17 00:00:00 2001
From: CapitainMorgan <40363984+CapitainMorgan@users.noreply.github.com>
Date: Fri, 19 Mar 2021 14:25:14 +0100
Subject: [PATCH 3/7] modify my specs
---
specs/CapitainMorgan/PROTOCOL.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/specs/CapitainMorgan/PROTOCOL.md b/specs/CapitainMorgan/PROTOCOL.md
index 36704e2..cbfb179 100644
--- a/specs/CapitainMorgan/PROTOCOL.md
+++ b/specs/CapitainMorgan/PROTOCOL.md
@@ -4,7 +4,7 @@ TCP
> How does the client find the server (addresses and ports)?
-IDK
+port 2021 client, port 2021 serveur
> Who speaks first?
@@ -16,7 +16,7 @@ Client -> mult 5 2 -> serveur -> 10 -> Client
> What happens when a message is received from the other party? (semantics)
-IDK
+le verifie et le traite
> What is the syntax of the messages? How we generate and parse them? (syntax)
From 7203d184b38099e234ab6dec6fb6c59c90bef0d6 Mon Sep 17 00:00:00 2001
From: issolahma <22448610+issolahma@users.noreply.github.com>
Date: Fri, 26 Mar 2021 15:16:55 +0100
Subject: [PATCH 4/7] srv
---
.idea/.gitignore | 8 ++
...IGVD-RES-2021-Exercise-Protocol-Design.iml | 9 ++
.idea/misc.xml | 6 +
.idea/modules.xml | 8 ++
.idea/vcs.xml | 6 +
my-app/.idea/.gitignore | 8 ++
my-app/.idea/compiler.xml | 16 +++
my-app/.idea/encodings.xml | 6 +
my-app/.idea/jarRepositories.xml | 20 ++++
.../libraries/Maven__junit_junit_4_11.xml | 13 +++
.../Maven__org_hamcrest_hamcrest_core_1_3.xml | 13 +++
my-app/.idea/misc.xml | 11 ++
my-app/.idea/modules.xml | 8 ++
my-app/.idea/vcs.xml | 6 +
my-app/my-app.iml | 16 +++
my-app/pom.xml | 75 +++++++++++++
.../src/main/java/com/mycompany/app/App.java | 13 +++
.../mycompany/app/SingleThreadedServer.java | 105 ++++++++++++++++++
.../java/com/mycompany/app/TcpServers.java | 37 ++++++
.../test/java/com/mycompany/app/AppTest.java | 20 ++++
20 files changed, 404 insertions(+)
create mode 100644 .idea/.gitignore
create mode 100644 .idea/Teaching-HEIGVD-RES-2021-Exercise-Protocol-Design.iml
create mode 100644 .idea/misc.xml
create mode 100644 .idea/modules.xml
create mode 100644 .idea/vcs.xml
create mode 100644 my-app/.idea/.gitignore
create mode 100644 my-app/.idea/compiler.xml
create mode 100644 my-app/.idea/encodings.xml
create mode 100644 my-app/.idea/jarRepositories.xml
create mode 100644 my-app/.idea/libraries/Maven__junit_junit_4_11.xml
create mode 100644 my-app/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml
create mode 100644 my-app/.idea/misc.xml
create mode 100644 my-app/.idea/modules.xml
create mode 100644 my-app/.idea/vcs.xml
create mode 100644 my-app/my-app.iml
create mode 100644 my-app/pom.xml
create mode 100644 my-app/src/main/java/com/mycompany/app/App.java
create mode 100644 my-app/src/main/java/com/mycompany/app/SingleThreadedServer.java
create mode 100644 my-app/src/main/java/com/mycompany/app/TcpServers.java
create mode 100644 my-app/src/test/java/com/mycompany/app/AppTest.java
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..73f69e0
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/Teaching-HEIGVD-RES-2021-Exercise-Protocol-Design.iml b/.idea/Teaching-HEIGVD-RES-2021-Exercise-Protocol-Design.iml
new file mode 100644
index 0000000..d6ebd48
--- /dev/null
+++ b/.idea/Teaching-HEIGVD-RES-2021-Exercise-Protocol-Design.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..1763e15
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..b3f665c
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/my-app/.idea/.gitignore b/my-app/.idea/.gitignore
new file mode 100644
index 0000000..73f69e0
--- /dev/null
+++ b/my-app/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/my-app/.idea/compiler.xml b/my-app/.idea/compiler.xml
new file mode 100644
index 0000000..2fdf4df
--- /dev/null
+++ b/my-app/.idea/compiler.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/my-app/.idea/encodings.xml b/my-app/.idea/encodings.xml
new file mode 100644
index 0000000..63e9001
--- /dev/null
+++ b/my-app/.idea/encodings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/my-app/.idea/jarRepositories.xml b/my-app/.idea/jarRepositories.xml
new file mode 100644
index 0000000..712ab9d
--- /dev/null
+++ b/my-app/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/my-app/.idea/libraries/Maven__junit_junit_4_11.xml b/my-app/.idea/libraries/Maven__junit_junit_4_11.xml
new file mode 100644
index 0000000..f33320d
--- /dev/null
+++ b/my-app/.idea/libraries/Maven__junit_junit_4_11.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/my-app/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml b/my-app/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml
new file mode 100644
index 0000000..f58bbc1
--- /dev/null
+++ b/my-app/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/my-app/.idea/misc.xml b/my-app/.idea/misc.xml
new file mode 100644
index 0000000..972ec8d
--- /dev/null
+++ b/my-app/.idea/misc.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/my-app/.idea/modules.xml b/my-app/.idea/modules.xml
new file mode 100644
index 0000000..a8cfcc2
--- /dev/null
+++ b/my-app/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/my-app/.idea/vcs.xml b/my-app/.idea/vcs.xml
new file mode 100644
index 0000000..6c0b863
--- /dev/null
+++ b/my-app/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/my-app/my-app.iml b/my-app/my-app.iml
new file mode 100644
index 0000000..3f4fd58
--- /dev/null
+++ b/my-app/my-app.iml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/my-app/pom.xml b/my-app/pom.xml
new file mode 100644
index 0000000..8671f90
--- /dev/null
+++ b/my-app/pom.xml
@@ -0,0 +1,75 @@
+
+
+
+ 4.0.0
+
+ com.mycompany.app
+ my-app
+ 1.0-SNAPSHOT
+
+ my-app
+
+ http://www.example.com
+
+
+ UTF-8
+ 1.7
+ 1.7
+
+
+
+
+ junit
+ junit
+ 4.11
+ test
+
+
+
+
+
+
+
+
+ maven-clean-plugin
+ 3.1.0
+
+
+
+ maven-resources-plugin
+ 3.0.2
+
+
+ maven-compiler-plugin
+ 3.8.0
+
+
+ maven-surefire-plugin
+ 2.22.1
+
+
+ maven-jar-plugin
+ 3.0.2
+
+
+ maven-install-plugin
+ 2.5.2
+
+
+ maven-deploy-plugin
+ 2.8.2
+
+
+
+ maven-site-plugin
+ 3.7.1
+
+
+ maven-project-info-reports-plugin
+ 3.0.0
+
+
+
+
+
diff --git a/my-app/src/main/java/com/mycompany/app/App.java b/my-app/src/main/java/com/mycompany/app/App.java
new file mode 100644
index 0000000..77cf3e0
--- /dev/null
+++ b/my-app/src/main/java/com/mycompany/app/App.java
@@ -0,0 +1,13 @@
+package com.mycompany.app;
+
+/**
+ * Hello world!
+ *
+ */
+public class App
+{
+ public static void main( String[] args )
+ {
+ System.out.println( "Hello World!" );
+ }
+}
diff --git a/my-app/src/main/java/com/mycompany/app/SingleThreadedServer.java b/my-app/src/main/java/com/mycompany/app/SingleThreadedServer.java
new file mode 100644
index 0000000..15462a8
--- /dev/null
+++ b/my-app/src/main/java/com/mycompany/app/SingleThreadedServer.java
@@ -0,0 +1,105 @@
+package com.mycompany.app;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class implements a single-threaded TCP server. It is able to interact
+ * with only one client at the time. If a client tries to connect when
+ * the server is busy with another one, it will have to wait.
+ *
+ * @author Olivier Liechti
+ */
+public class SingleThreadedServer {
+
+ final static Logger LOG = Logger.getLogger(SingleThreadedServer.class.getName());
+
+ int port;
+
+ /**
+ * Constructor
+ * @param port the port to listen on
+ */
+ public SingleThreadedServer(int port) {
+ this.port = port;
+ }
+
+ /**
+ * This method initiates the process. The server creates a socket and binds
+ * it to the previously specified port. It then waits for clients in a infinite
+ * loop. When a client arrives, the server will read its input line by line
+ * and send back the data converted to uppercase. This will continue until
+ * the client sends the "BYE" command.
+ */
+ public void serveClients() {
+ ServerSocket serverSocket;
+ Socket clientSocket = null;
+ BufferedReader in = null;
+ PrintWriter out = null;
+
+ try {
+ serverSocket = new ServerSocket(port);
+ } catch (IOException ex) {
+ LOG.log(Level.SEVERE, null, ex);
+ return;
+ }
+
+ while (true) {
+ try {
+
+ LOG.log(Level.INFO, "Waiting (blocking) for a new client on port {0}", port);
+ clientSocket = serverSocket.accept();
+ in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
+ out = new PrintWriter(clientSocket.getOutputStream());
+ String line;
+ boolean shouldRun = true;
+
+ out.println("Welcome to the Single-Threaded Server.\nSend me text lines and conclude with the BYE command.");
+ out.flush();
+ LOG.info("Reading until client sends BYE or closes the connection...");
+ while ( (shouldRun) && (line = in.readLine()) != null ) {
+ if (line.equalsIgnoreCase("quit")) {
+ shouldRun = false;
+ } else if (line.split(" ")[0].equalsIgnoreCase("compute")){
+ out.println("Compute ok\r\n");
+ } else {
+ out.println("Error 400. Syntax error\r\n");
+ }
+ out.println("> " + line.toUpperCase());
+ out.flush();
+ }
+
+ LOG.info("Cleaning up resources...");
+ clientSocket.close();
+ in.close();
+ out.close();
+
+ } catch (IOException ex) {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException ex1) {
+ LOG.log(Level.SEVERE, ex1.getMessage(), ex1);
+ }
+ }
+ if (out != null) {
+ out.close();
+ }
+ if (clientSocket != null) {
+ try {
+ clientSocket.close();
+ } catch (IOException ex1) {
+ LOG.log(Level.SEVERE, ex1.getMessage(), ex1);
+ }
+ }
+ LOG.log(Level.SEVERE, ex.getMessage(), ex);
+ }
+ }
+ }
+}
diff --git a/my-app/src/main/java/com/mycompany/app/TcpServers.java b/my-app/src/main/java/com/mycompany/app/TcpServers.java
new file mode 100644
index 0000000..630754a
--- /dev/null
+++ b/my-app/src/main/java/com/mycompany/app/TcpServers.java
@@ -0,0 +1,37 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.mycompany.app;
+
+/**
+ * This application shows the difference between a single threaded TCP server
+ * and a multi threaded TCP server. It shows that the first one is only able to
+ * process one client at the time, which is obviously not really an option for
+ * most applications. The second one uses n+1 threads, where n is the number of
+ * clients currently connected. The extra thread is used to wait for new clients
+ * to arrive, in a loop.
+ *
+ * The application starts the multi-threaded server on port 2323 and the
+ * single-threaded server on port 2424. Use several terminals and the telnet
+ * command to (try to) connect to the servers and compare the behavior.
+ *
+ * @author Olivier Liechti
+ */
+public class TcpServers {
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String[] args) {
+ System.setProperty("java.util.logging.SimpleFormatter.format", "%5$s %n");
+
+ //MultiThreadedServer multi = new MultiThreadedServer(2323);
+ //multi.serveClients();
+
+ SingleThreadedServer single = new SingleThreadedServer(2424);
+ single.serveClients();
+ }
+
+}
diff --git a/my-app/src/test/java/com/mycompany/app/AppTest.java b/my-app/src/test/java/com/mycompany/app/AppTest.java
new file mode 100644
index 0000000..81ac345
--- /dev/null
+++ b/my-app/src/test/java/com/mycompany/app/AppTest.java
@@ -0,0 +1,20 @@
+package com.mycompany.app;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+{
+ /**
+ * Rigorous Test :-)
+ */
+ @Test
+ public void shouldAnswerWithTrue()
+ {
+ assertTrue( true );
+ }
+}
From 7b5d8daf59371a341dc6798735b769b00c0a44f8 Mon Sep 17 00:00:00 2001
From: issolahma <22448610+issolahma@users.noreply.github.com>
Date: Fri, 26 Mar 2021 17:52:52 +0100
Subject: [PATCH 5/7] Update pom.xml, manifest error
---
my-app/pom.xml | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/my-app/pom.xml b/my-app/pom.xml
index 8671f90..7e2d313 100644
--- a/my-app/pom.xml
+++ b/my-app/pom.xml
@@ -69,6 +69,26 @@
maven-project-info-reports-plugin
3.0.0
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.1.0
+
+
+
+
+
+ com.mycompany.app.TcpServers
+
+
+
+
+
+
From 9e23d14e80b5dbfcc3a3df54f53d5bc788b5c51c Mon Sep 17 00:00:00 2001
From: issolahma <22448610+issolahma@users.noreply.github.com>
Date: Tue, 30 Mar 2021 14:36:42 +0200
Subject: [PATCH 6/7] add multi thread
---
.../mycompany/app/MultiThreadedServer.java | 174 ++++++++++++++++++
.../mycompany/app/SingleThreadedServer.java | 33 +++-
.../java/com/mycompany/app/TcpServers.java | 8 +-
3 files changed, 207 insertions(+), 8 deletions(-)
create mode 100644 my-app/src/main/java/com/mycompany/app/MultiThreadedServer.java
diff --git a/my-app/src/main/java/com/mycompany/app/MultiThreadedServer.java b/my-app/src/main/java/com/mycompany/app/MultiThreadedServer.java
new file mode 100644
index 0000000..29a1590
--- /dev/null
+++ b/my-app/src/main/java/com/mycompany/app/MultiThreadedServer.java
@@ -0,0 +1,174 @@
+package com.mycompany.app;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This class implements a multi-threaded TCP server. It is able to interact
+ * with several clients at the time, as well as to continue listening for
+ * connection requests.
+ *
+ * @author Olivier Liechti
+ */
+public class MultiThreadedServer {
+
+ final static Logger LOG = Logger.getLogger(MultiThreadedServer.class.getName());
+
+ int port;
+
+ /**
+ * Constructor
+ *
+ * @param port the port to listen on
+ */
+ public MultiThreadedServer(int port) {
+ this.port = port;
+ }
+
+ /**
+ * This method initiates the process. The server creates a socket and binds it
+ * to the previously specified port. It then waits for clients in a infinite
+ * loop. When a client arrives, the server will read its input line by line
+ * and send back the data converted to uppercase. This will continue until the
+ * client sends the "BYE" command.
+ */
+ public void serveClients() {
+ LOG.info("Starting the Receptionist Worker on a new thread...");
+ new Thread(new ReceptionistWorker()).start();
+ }
+
+ /**
+ * This inner class implements the behavior of the "receptionist", whose
+ * responsibility is to listen for incoming connection requests. As soon as a
+ * new client has arrived, the receptionist delegates the processing to a
+ * "servant" who will execute on its own thread.
+ */
+ private class ReceptionistWorker implements Runnable {
+
+ @Override
+ public void run() {
+ ServerSocket serverSocket;
+
+ try {
+ serverSocket = new ServerSocket(port);
+ } catch (IOException ex) {
+ LOG.log(Level.SEVERE, null, ex);
+ return;
+ }
+
+ while (true) {
+ LOG.log(Level.INFO, "Waiting (blocking) for a new client on port {0}", port);
+ try {
+ Socket clientSocket = serverSocket.accept();
+ LOG.info("A new client has arrived. Starting a new thread and delegating work to a new servant...");
+ new Thread(new ServantWorker(clientSocket)).start();
+ } catch (IOException ex) {
+ Logger.getLogger(MultiThreadedServer.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ }
+
+ /**
+ * This inner class implements the behavior of the "servants", whose
+ * responsibility is to take care of clients once they have connected. This
+ * is where we implement the application protocol logic, i.e. where we read
+ * data sent by the client and where we generate the responses.
+ */
+ private class ServantWorker implements Runnable {
+
+ Socket clientSocket;
+ BufferedReader in = null;
+ PrintWriter out = null;
+
+ public ServantWorker(Socket clientSocket) {
+ try {
+ this.clientSocket = clientSocket;
+ in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
+ out = new PrintWriter(clientSocket.getOutputStream());
+ } catch (IOException ex) {
+ Logger.getLogger(MultiThreadedServer.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+
+ @Override
+ public void run() {
+ String line;
+ boolean shouldRun = true;
+
+ out.println("Welcome to the Multi-Threaded Server.\nSend me text lines and conclude with the QUIT command.");
+ out.flush();
+ try {
+ LOG.info("Reading until client sends BYE or closes the connection...");
+ while ((shouldRun) && (line = in.readLine()) != null) {
+ int nbArgs = line.split(" ").length;
+ if (line.equalsIgnoreCase("quit")) {
+ shouldRun = false;
+ } else if (nbArgs == 4 && line.split(" ")[0].equalsIgnoreCase("compute")){
+ boolean numOk = true;
+ double num1 =0, num2=0;
+ try {
+ num1 = Double.parseDouble(line.split(" ")[2]);
+ num2 = Double.parseDouble(line.split(" ")[3]);
+ } catch (NumberFormatException nfe) {
+ out.println("Error 400. Syntax error\r\n");
+ out.println("Must be number\n");
+ numOk = false;
+ }
+ if (numOk) {
+ double result;
+ switch (line.split(" ")[1]) {
+ case "ADD":
+ case "add":
+ result = num1 + num2;
+ out.println(num1 + "+" + num2 + "=" + result +"\r\n");
+ break;
+ case "MULT":
+ case "mult":
+ result = num1 * num2;
+ out.println(num1 + "*" + num2 + "=" + result +"\r\n");
+ break;
+ }
+ }
+
+ }
+
+ out.println("> " + line.toUpperCase());
+ out.flush();
+ }
+
+ LOG.info("Cleaning up resources...");
+ clientSocket.close();
+ in.close();
+ out.close();
+
+ } catch (IOException ex) {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException ex1) {
+ LOG.log(Level.SEVERE, ex1.getMessage(), ex1);
+ }
+ }
+ if (out != null) {
+ out.close();
+ }
+ if (clientSocket != null) {
+ try {
+ clientSocket.close();
+ } catch (IOException ex1) {
+ LOG.log(Level.SEVERE, ex1.getMessage(), ex1);
+ }
+ }
+ LOG.log(Level.SEVERE, ex.getMessage(), ex);
+ }
+ }
+ }
+ }
+}
diff --git a/my-app/src/main/java/com/mycompany/app/SingleThreadedServer.java b/my-app/src/main/java/com/mycompany/app/SingleThreadedServer.java
index 15462a8..1967673 100644
--- a/my-app/src/main/java/com/mycompany/app/SingleThreadedServer.java
+++ b/my-app/src/main/java/com/mycompany/app/SingleThreadedServer.java
@@ -60,14 +60,39 @@ public void serveClients() {
String line;
boolean shouldRun = true;
- out.println("Welcome to the Single-Threaded Server.\nSend me text lines and conclude with the BYE command.");
+ out.println("Welcome to the Single-Threaded Server.\nSend me text lines and conclude with the QUIT command.");
out.flush();
- LOG.info("Reading until client sends BYE or closes the connection...");
+ LOG.info("Reading until client sends quit or closes the connection...");
while ( (shouldRun) && (line = in.readLine()) != null ) {
+ int nbArgs = line.split(" ").length;
if (line.equalsIgnoreCase("quit")) {
shouldRun = false;
- } else if (line.split(" ")[0].equalsIgnoreCase("compute")){
- out.println("Compute ok\r\n");
+ } else if (nbArgs == 4 && line.split(" ")[0].equalsIgnoreCase("compute")){
+ boolean numOk = true;
+ double num1 =0, num2=0;
+ try {
+ num1 = Double.parseDouble(line.split(" ")[2]);
+ num2 = Double.parseDouble(line.split(" ")[3]);
+ } catch (NumberFormatException nfe) {
+ out.println("Error 400. Syntax error\r\n");
+ out.println("Must be number\n");
+ numOk = false;
+ }
+ if (numOk) {
+ double result;
+ switch (line.split(" ")[1]) {
+ case "ADD":
+ case "add":
+ result = num1 + num2;
+ out.println(num1 + "+" + num2 + "=" + result +"\r\n");
+ break;
+ case "MULT":
+ case "mult":
+ result = num1 * num2;
+ out.println(num1 + "*" + num2 + "=" + result +"\r\n");
+ break;
+ }
+ }
} else {
out.println("Error 400. Syntax error\r\n");
}
diff --git a/my-app/src/main/java/com/mycompany/app/TcpServers.java b/my-app/src/main/java/com/mycompany/app/TcpServers.java
index 630754a..2b6b663 100644
--- a/my-app/src/main/java/com/mycompany/app/TcpServers.java
+++ b/my-app/src/main/java/com/mycompany/app/TcpServers.java
@@ -27,11 +27,11 @@ public class TcpServers {
public static void main(String[] args) {
System.setProperty("java.util.logging.SimpleFormatter.format", "%5$s %n");
- //MultiThreadedServer multi = new MultiThreadedServer(2323);
- //multi.serveClients();
+ MultiThreadedServer multi = new MultiThreadedServer(2323);
+ multi.serveClients();
- SingleThreadedServer single = new SingleThreadedServer(2424);
- single.serveClients();
+ //SingleThreadedServer single = new SingleThreadedServer(2424);
+ //single.serveClients();
}
}
From 402c84347762d12a5e6d3e3ca16dd86762f120cd Mon Sep 17 00:00:00 2001
From: nroot
Date: Tue, 30 Mar 2021 17:56:42 +0200
Subject: [PATCH 7/7] Client TCP
---
client/DumbHttpClient.iml | 13 +++
client/pom.xml | 39 ++++++++
.../heigvd/res/examples/DumbHttpClient.java | 89 +++++++++++++++++++
3 files changed, 141 insertions(+)
create mode 100644 client/DumbHttpClient.iml
create mode 100644 client/pom.xml
create mode 100644 client/src/main/java/ch/heigvd/res/examples/DumbHttpClient.java
diff --git a/client/DumbHttpClient.iml b/client/DumbHttpClient.iml
new file mode 100644
index 0000000..b872d82
--- /dev/null
+++ b/client/DumbHttpClient.iml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/client/pom.xml b/client/pom.xml
new file mode 100644
index 0000000..c35b865
--- /dev/null
+++ b/client/pom.xml
@@ -0,0 +1,39 @@
+
+
+ 4.0.0
+ ch.heigvd.res.examples
+ DumbHttpClient
+ 1.0-SNAPSHOT
+ jar
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 2.3
+
+
+ package
+
+ shade
+
+
+ true
+ standalone
+
+
+ ch.heigvd.res.examples.DumbHttpClient
+
+
+
+
+
+
+
+
+
+ UTF-8
+ 1.7
+ 1.7
+
+
\ No newline at end of file
diff --git a/client/src/main/java/ch/heigvd/res/examples/DumbHttpClient.java b/client/src/main/java/ch/heigvd/res/examples/DumbHttpClient.java
new file mode 100644
index 0000000..dceeb25
--- /dev/null
+++ b/client/src/main/java/ch/heigvd/res/examples/DumbHttpClient.java
@@ -0,0 +1,89 @@
+package ch.heigvd.res.examples;
+
+import java.io.*;
+import java.net.Socket;
+import java.util.Scanner;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * This is not really an HTTP client, but rather a very simple program that
+ * establishes a TCP connection with a real HTTP server. Once connected, the
+ * client sends "garbage" to the server (the client does not send a proper
+ * HTTP request that the server would understand). The client then reads the
+ * response sent back by the server and logs it onto the console.
+ *
+ * @author Olivier Liechti
+ */
+public class DumbHttpClient {
+
+ static final Logger LOG = Logger.getLogger(DumbHttpClient.class.getName());
+
+ final static int BUFFER_SIZE = 1024;
+
+ /**
+ * This method does the whole processing
+ */
+ public void sendRequest() {
+ Socket clientSocket = null;
+ OutputStream os = null;
+ InputStream is = null;
+
+ try {
+ clientSocket = new Socket("localhost", 2323);
+ os = clientSocket.getOutputStream();
+ is = clientSocket.getInputStream();
+
+ Scanner sc= new Scanner(System.in);
+ String userInput = "";
+
+ while(userInput != "QUIT") {
+ LOG.log(Level.INFO, "Start");
+ ByteArrayOutputStream responseBuffer = new ByteArrayOutputStream();
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int newBytes;
+ while ((newBytes = is.read(buffer)) != -1) {
+ responseBuffer.write(buffer, 0, newBytes);
+ }
+
+ LOG.log(Level.INFO, "Response sent by the server: ");
+ LOG.log(Level.INFO, responseBuffer.toString());
+
+ userInput = sc.nextLine();
+
+ os.write(userInput.getBytes());
+ }
+ } catch (IOException ex) {
+ LOG.log(Level.SEVERE, null, ex);
+ } finally {
+ try {
+ is.close();
+ } catch (IOException ex) {
+ Logger.getLogger(DumbHttpClient.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ try {
+ os.close();
+ } catch (IOException ex) {
+ Logger.getLogger(DumbHttpClient.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ try {
+ clientSocket.close();
+ } catch (IOException ex) {
+ Logger.getLogger(DumbHttpClient.class.getName()).log(Level.SEVERE, null, ex);
+ }
+ }
+ LOG.log(Level.INFO, "QUIT");
+ }
+
+ /**
+ * @param args the command line arguments
+ */
+ public static void main(String[] args) {
+ System.setProperty("java.util.logging.SimpleFormatter.format", "%5$s %n");
+
+ DumbHttpClient client = new DumbHttpClient();
+ client.sendRequest();
+
+ }
+
+}