From d3b523048fc86da81ba0afbfa85c83f497d4cb9a Mon Sep 17 00:00:00 2001 From: Xeon0X Date: Mon, 31 Mar 2025 20:58:05 +0200 Subject: [PATCH 1/5] refactor: add arguments support to run client or server --- .project | 28 ++++++++++++ .settings/org.eclipse.buildship.core.prefs | 13 ++++++ README.md | 36 ++++++++++++++++ app/.classpath | 19 ++++++++ app/.project | 34 +++++++++++++++ .../org.eclipse.buildship.core.prefs | 2 + app/build.gradle | 16 +++++++ app/src/main/java/clientserver/App.java | 29 +++++++++++-- .../clientserver/{ => client}/Client.java | 26 ++++++++--- .../{ => common}/MistralDirectAPI.java | 2 +- .../{ => server}/ClientHandler.java | 43 +------------------ 11 files changed, 198 insertions(+), 50 deletions(-) create mode 100644 .project create mode 100644 .settings/org.eclipse.buildship.core.prefs create mode 100644 app/.classpath create mode 100644 app/.project create mode 100644 app/.settings/org.eclipse.buildship.core.prefs rename app/src/main/java/clientserver/{ => client}/Client.java (71%) rename app/src/main/java/clientserver/{ => common}/MistralDirectAPI.java (98%) rename app/src/main/java/clientserver/{ => server}/ClientHandler.java (66%) diff --git a/.project b/.project new file mode 100644 index 0000000..9f05120 --- /dev/null +++ b/.project @@ -0,0 +1,28 @@ + + + ClientServer + Project ClientServer created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + + + 1743445961452 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + + diff --git a/.settings/org.eclipse.buildship.core.prefs b/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000..d230334 --- /dev/null +++ b/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,13 @@ +arguments=--init-script /home/xeon0x/.var/app/dev.zed.Zed/data/zed/extensions/work/java/jdtls/jdt-language-server-1.46.0-202503271314/configuration/org.eclipse.osgi/58/0/.cp/gradle/init/init.gradle +auto.sync=false +build.scans.enabled=false +connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) +connection.project.dir= +eclipse.preferences.version=1 +gradle.user.home= +java.home=/usr/lib64/jvm/java-21-openjdk-21 +jvm.arguments= +offline.mode=false +override.workspace.settings=true +show.console.view=true +show.executions.view=true diff --git a/README.md b/README.md index c940f86..2d82657 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,39 @@ +# ClientServer + +## Build + +```bash +./gradlew build +``` + +## Run + +### Client + +```bash +./gradlew run --args='client' +``` + +or + +```bash +./gradlew runServer +``` + +### Server + +```bash +./gradlew run --args='server' +``` + +or + +```bash +./gradlew runServer +``` + +## Documentation + ```mermaid sequenceDiagram Note over Client, Serveur: DatagramSocket("localhost", 66666) diff --git a/app/.classpath b/app/.classpath new file mode 100644 index 0000000..282ada5 --- /dev/null +++ b/app/.classpath @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/app/.project b/app/.project new file mode 100644 index 0000000..ecb5e8f --- /dev/null +++ b/app/.project @@ -0,0 +1,34 @@ + + + app + Project app created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + + + 1743445961456 + + 30 + + org.eclipse.core.resources.regexFilterMatcher + node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ + + + + diff --git a/app/.settings/org.eclipse.buildship.core.prefs b/app/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000..b1886ad --- /dev/null +++ b/app/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir=.. +eclipse.preferences.version=1 diff --git a/app/build.gradle b/app/build.gradle index 990d74d..1505e06 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -40,3 +40,19 @@ tasks.named('test') { // Use JUnit Platform for unit tests. useJUnitPlatform() } + +task runServer(type: JavaExec) { + description = 'Runs the server' + group = 'application' + mainClass = application.mainClass + classpath = sourceSets.main.runtimeClasspath + args = ['server'] +} + +task runClient(type: JavaExec) { + description = 'Runs the client' + group = 'application' + mainClass = application.mainClass + classpath = sourceSets.main.runtimeClasspath + args = ['client'] +} diff --git a/app/src/main/java/clientserver/App.java b/app/src/main/java/clientserver/App.java index 94a7196..90246c9 100644 --- a/app/src/main/java/clientserver/App.java +++ b/app/src/main/java/clientserver/App.java @@ -1,5 +1,8 @@ package clientserver; +import clientserver.client.Client; +import clientserver.server.ClientHandler; + public class App { public String getGreeting() { @@ -7,8 +10,28 @@ public class App { } public static void main(String[] args) { - System.out.println(new App().getGreeting()); - ClientHandler.main(new String[] {}); - // MistralDirectAPI.main(new String[] {}); + if (args.length == 0) { + System.out.println( + "Please use --args='client' or --args='server'." + ); + return; + } + + String mode = args[0]; + + switch (mode.toLowerCase()) { + case "client": + // Run the client + System.out.println("Starting client..."); + Client.main(new String[] {}); + break; + case "server": + // Run the server + System.out.println("Starting server..."); + ClientHandler.main(new String[] {}); + break; + default: + System.out.println("Unknown mode: " + mode); + } } } diff --git a/app/src/main/java/clientserver/Client.java b/app/src/main/java/clientserver/client/Client.java similarity index 71% rename from app/src/main/java/clientserver/Client.java rename to app/src/main/java/clientserver/client/Client.java index e209afa..b10c4fa 100644 --- a/app/src/main/java/clientserver/Client.java +++ b/app/src/main/java/clientserver/client/Client.java @@ -1,10 +1,11 @@ -package clientserver; +package clientserver.client; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class Client { + public static void main(String[] args) { try { // 1 - Création du canal avec un port libre @@ -16,15 +17,26 @@ public class Client { String message = "Hello Server"; byte[] envoyees = message.getBytes(); DatagramPacket paquetEnvoye = new DatagramPacket( - envoyees, envoyees.length, adresseServeur, portServeur); + envoyees, + envoyees.length, + adresseServeur, + portServeur + ); socketClient.send(paquetEnvoye); System.out.println("Message envoyé au serveur"); // 3 - Recevoir byte[] recues = new byte[1024]; // tampon de réception - DatagramPacket paquetRecu = new DatagramPacket(recues, recues.length); + DatagramPacket paquetRecu = new DatagramPacket( + recues, + recues.length + ); socketClient.receive(paquetRecu); - String reponse = new String(paquetRecu.getData(), 0, paquetRecu.getLength()); + String reponse = new String( + paquetRecu.getData(), + 0, + paquetRecu.getLength() + ); if (reponse.startsWith("PORT:")) { int newPort = Integer.parseInt(reponse.substring(5)); @@ -35,7 +47,11 @@ public class Client { String messagePort = "Message au nouveau port"; byte[] envoyeesPort = messagePort.getBytes(); DatagramPacket paquetPort = new DatagramPacket( - envoyeesPort, envoyeesPort.length, adresseServeur, newPort); + envoyeesPort, + envoyeesPort.length, + adresseServeur, + newPort + ); socketClient.send(paquetPort); } diff --git a/app/src/main/java/clientserver/MistralDirectAPI.java b/app/src/main/java/clientserver/common/MistralDirectAPI.java similarity index 98% rename from app/src/main/java/clientserver/MistralDirectAPI.java rename to app/src/main/java/clientserver/common/MistralDirectAPI.java index 25c1318..65bc0bc 100644 --- a/app/src/main/java/clientserver/MistralDirectAPI.java +++ b/app/src/main/java/clientserver/common/MistralDirectAPI.java @@ -1,4 +1,4 @@ -package clientserver; +package clientserver.common; import java.io.FileInputStream; import java.io.IOException; diff --git a/app/src/main/java/clientserver/ClientHandler.java b/app/src/main/java/clientserver/server/ClientHandler.java similarity index 66% rename from app/src/main/java/clientserver/ClientHandler.java rename to app/src/main/java/clientserver/server/ClientHandler.java index a9aa42d..d62389d 100644 --- a/app/src/main/java/clientserver/ClientHandler.java +++ b/app/src/main/java/clientserver/server/ClientHandler.java @@ -1,4 +1,4 @@ -package clientserver; +package clientserver.server; import java.net.DatagramPacket; import java.net.DatagramSocket; @@ -7,7 +7,7 @@ import java.net.InetSocketAddress; public class ClientHandler { - static void main(String[] args) { + public static void main(String[] args) { int port = 6666; boolean running = true; DatagramSocket socketServer = null; @@ -94,43 +94,4 @@ public class ClientHandler { System.out.println(e); } } - // public static void main(String[] args) { - // try { - // // 1 - Création du canal - // DatagramSocket socketServeur = new DatagramSocket(null); - // // 2 - Réservation du port - // InetSocketAddress adresse = new InetSocketAddress( - // "localhost", - // 6666 - // ); - // socketServeur.bind(adresse); - // byte[] recues = new byte[1024]; // tampon d'émission - // byte[] envoyees; // tampon de réception - // // 3 - Recevoir - // DatagramPacket paquetRecu = new DatagramPacket( - // recues, - // recues.length - // ); - // socketServeur.receive(paquetRecu); - // InetAddress adrClient = paquetRecu.getAddress(); - // int prtClient = paquetRecu.getPort(); - // System.out.println( - // "Nouveau client : @" + adrClient + ":" + prtClient - // ); - // // 4 - Émettre - // String reponse = "Serveur RX302 ready"; - // envoyees = reponse.getBytes(); - // DatagramPacket paquetEnvoye = new DatagramPacket( - // envoyees, - // envoyees.length, - // adrClient, - // prtClient - // ); - // socketServeur.send(paquetEnvoye); - // // 5 - Libérer le canal - // socketServeur.close(); - // } catch (Exception e) { - // System.err.println(e); - // } - // } } From f0ea538c219e7750c90815f36223d65157969d59 Mon Sep 17 00:00:00 2001 From: Xeon0X Date: Mon, 31 Mar 2025 21:45:32 +0200 Subject: [PATCH 2/5] refactor: split server into mutliples methods --- app/src/main/java/clientserver/App.java | 4 +- .../main/java/clientserver/client/Client.java | 16 +++ .../clientserver/server/ClientHandler.java | 97 ------------------- .../main/java/clientserver/server/Server.java | 91 +++++++++++++++++ 4 files changed, 109 insertions(+), 99 deletions(-) delete mode 100644 app/src/main/java/clientserver/server/ClientHandler.java create mode 100644 app/src/main/java/clientserver/server/Server.java diff --git a/app/src/main/java/clientserver/App.java b/app/src/main/java/clientserver/App.java index 90246c9..9f5f31d 100644 --- a/app/src/main/java/clientserver/App.java +++ b/app/src/main/java/clientserver/App.java @@ -1,7 +1,7 @@ package clientserver; import clientserver.client.Client; -import clientserver.server.ClientHandler; +import clientserver.server.Server; public class App { @@ -28,7 +28,7 @@ public class App { case "server": // Run the server System.out.println("Starting server..."); - ClientHandler.main(new String[] {}); + Server.run(); break; default: System.out.println("Unknown mode: " + mode); diff --git a/app/src/main/java/clientserver/client/Client.java b/app/src/main/java/clientserver/client/Client.java index b10c4fa..4449a71 100644 --- a/app/src/main/java/clientserver/client/Client.java +++ b/app/src/main/java/clientserver/client/Client.java @@ -6,6 +6,22 @@ import java.net.InetAddress; public class Client { + InetAddress clientAddress; + int clientPort; + + public InetAddress getClientAddress() { + return clientAddress; + } + + public int getClientPort() { + return clientPort; + } + + public Client(InetAddress address, int port) { + this.clientAddress = address; + this.clientPort = port; + } + public static void main(String[] args) { try { // 1 - Création du canal avec un port libre diff --git a/app/src/main/java/clientserver/server/ClientHandler.java b/app/src/main/java/clientserver/server/ClientHandler.java deleted file mode 100644 index d62389d..0000000 --- a/app/src/main/java/clientserver/server/ClientHandler.java +++ /dev/null @@ -1,97 +0,0 @@ -package clientserver.server; - -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.InetSocketAddress; - -public class ClientHandler { - - public static void main(String[] args) { - int port = 6666; - boolean running = true; - DatagramSocket socketServer = null; - try { - socketServer = new DatagramSocket(null); - // 2 - Réservation du port - InetSocketAddress address = new InetSocketAddress( - "localhost", - port - ); - socketServer.bind(address); - } catch (Exception e) { - e.printStackTrace(); - } - - while (running) { - try { - // 1 - Création du canal - - // 3 - Recevoir - byte[] recues = new byte[1024]; // tampon de réception - DatagramPacket receivedPacket = new DatagramPacket( - recues, - recues.length - ); - socketServer.receive(receivedPacket); - InetAddress clientAddress = receivedPacket.getAddress(); - int clientPort = receivedPacket.getPort(); - System.out.println( - "Nouveau client : @" + clientAddress + ":" + clientPort - ); - DatagramSocket socket = new DatagramSocket(); // Reserve new port - - String response = "PORT:" + socket.getLocalPort(); - System.out.println(response); - byte[] envoyees; // tampon d'émission - envoyees = response.getBytes(); - DatagramPacket packetToSend = new DatagramPacket( - envoyees, - envoyees.length, - clientAddress, - clientPort - ); - socketServer.send(packetToSend); - Thread thread = new Thread(() -> createThread(socket)); - thread.start(); - } catch (Exception e) { - System.err.println(e); - } - } - - socketServer.close(); - } - - public static void createThread(DatagramSocket socketClientThread) { - try { - byte[] recues = new byte[1024]; // tampon de réception - DatagramPacket receivedPacket = new DatagramPacket( - recues, - recues.length - ); - socketClientThread.receive(receivedPacket); - String message = new String( - receivedPacket.getData(), - 0, - receivedPacket.getLength() - ); - System.out.println("Received message: " + message); - } catch (Exception e) { - System.err.println(e); - } - } - - static void scannerUDP(int startPort, int endPort) { - try { - for (int i = startPort; i < endPort; i++) { - try (DatagramSocket socket = new DatagramSocket(i)) {} catch ( - Exception e - ) { - System.out.println("Port n°" + i + " déjà occupé"); - } - } - } catch (Exception e) { - System.out.println(e); - } - } -} diff --git a/app/src/main/java/clientserver/server/Server.java b/app/src/main/java/clientserver/server/Server.java new file mode 100644 index 0000000..92a947c --- /dev/null +++ b/app/src/main/java/clientserver/server/Server.java @@ -0,0 +1,91 @@ +package clientserver.server; + +import clientserver.client.Client; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; + +public class Server { + + private int mainServerPort; + private DatagramSocket mainServerSocket; + + public Server(int port) { + this.mainServerPort = port; + mainServerSocket = createSocket(this.mainServerPort); + } + + public Server() { + this.mainServerPort = 6666; + mainServerSocket = createSocket(this.mainServerPort); + } + + private DatagramSocket createSocket(int port) { + DatagramSocket socket = null; + try { + socket = new DatagramSocket(port); + } catch (Exception e) { + System.err.println("Failed to bind server socket"); + e.printStackTrace(); + } + return socket; + } + + private DatagramPacket read(DatagramSocket socket) { + byte[] receivedData = new byte[1024]; + DatagramPacket receivedPacket = new DatagramPacket( + receivedData, + receivedData.length + ); + + try { + socket.receive(receivedPacket); // Blocking call + } catch (IOException e) { + e.printStackTrace(); + } + return receivedPacket; + } + + private Client getClient(DatagramPacket packet) { + return new Client(packet.getAddress(), packet.getPort()); + } + + // public void test(String[] args) { + // while (mainServerPortListening) { + // try { + // DatagramSocket socket = new DatagramSocket(); // Reserve new port + + // String response = "PORT:" + socket.getLocalPort(); + // System.out.println(response); + // byte[] envoyees; // tampon d'émission + // envoyees = response.getBytes(); + // DatagramPacket packetToSend = new DatagramPacket( + // envoyees, + // envoyees.length, + // clientAddress, + // clientPort + // ); + // mainServerSocket.send(packetToSend); + // Thread thread = new Thread(() -> createThread(socket)); + // thread.start(); + // } catch (Exception e) { + // System.err.println(e); + // } + // } + + // mainServerSocket.close(); + // } + + public static void run() { + System.out.println("Server started"); + Server server = new Server(); + DatagramPacket packet = server.read(server.mainServerSocket); + Client client = server.getClient(packet); + System.out.println( + "Client: " + + client.getClientAddress() + + ":" + + client.getClientPort() + ); + } +} From 8599c149799b01e3adcc745a929e0a23158b1a86 Mon Sep 17 00:00:00 2001 From: Xeon0X Date: Mon, 31 Mar 2025 22:40:36 +0200 Subject: [PATCH 3/5] refactor: server --- app/build.gradle | 4 +- app/src/main/java/clientserver/App.java | 42 +++++++++---- .../main/java/clientserver/client/Client.java | 12 ++-- .../main/java/clientserver/server/Server.java | 61 ++++++++++--------- 4 files changed, 72 insertions(+), 47 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 1505e06..fc08b4d 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -46,7 +46,7 @@ task runServer(type: JavaExec) { group = 'application' mainClass = application.mainClass classpath = sourceSets.main.runtimeClasspath - args = ['server'] + args = ['--server'] } task runClient(type: JavaExec) { @@ -54,5 +54,5 @@ task runClient(type: JavaExec) { group = 'application' mainClass = application.mainClass classpath = sourceSets.main.runtimeClasspath - args = ['client'] + args = ['--client'] } diff --git a/app/src/main/java/clientserver/App.java b/app/src/main/java/clientserver/App.java index 9f5f31d..bc0006c 100644 --- a/app/src/main/java/clientserver/App.java +++ b/app/src/main/java/clientserver/App.java @@ -10,28 +10,48 @@ public class App { } public static void main(String[] args) { - if (args.length == 0) { - System.out.println( - "Please use --args='client' or --args='server'." - ); + String mode = null; + + // Parse arguments + for (String arg : args) { + switch (arg.toLowerCase()) { + case "--client": + mode = "client"; + break; + case "--server": + mode = "server"; + break; + default: + System.out.println("Unknown argument: " + arg); + printUsage(); + return; + } + } + + // Check if mode is specified + if (mode == null) { + System.out.println("No mode specified."); + printUsage(); return; } - String mode = args[0]; - - switch (mode.toLowerCase()) { + // Execute based on mode + switch (mode) { case "client": - // Run the client System.out.println("Starting client..."); Client.main(new String[] {}); break; case "server": - // Run the server System.out.println("Starting server..."); Server.run(); break; - default: - System.out.println("Unknown mode: " + mode); } } + + private static void printUsage() { + System.out.println("Usage: ./gradlew run --args='option'"); + System.out.println("Options:"); + System.out.println(" --client Run in client mode"); + System.out.println(" --server Run in server mode"); + } } diff --git a/app/src/main/java/clientserver/client/Client.java b/app/src/main/java/clientserver/client/Client.java index 4449a71..9a046df 100644 --- a/app/src/main/java/clientserver/client/Client.java +++ b/app/src/main/java/clientserver/client/Client.java @@ -9,12 +9,16 @@ public class Client { InetAddress clientAddress; int clientPort; - public InetAddress getClientAddress() { - return clientAddress; + public void setPort(int port) { + this.clientPort = port; } - public int getClientPort() { - return clientPort; + public int getPort() { + return this.clientPort; + } + + public InetAddress getAddress() { + return this.clientAddress; } public Client(InetAddress address, int port) { diff --git a/app/src/main/java/clientserver/server/Server.java b/app/src/main/java/clientserver/server/Server.java index 92a947c..5d0e8c9 100644 --- a/app/src/main/java/clientserver/server/Server.java +++ b/app/src/main/java/clientserver/server/Server.java @@ -31,6 +31,17 @@ public class Server { return socket; } + private DatagramSocket getNewSocket() { + DatagramSocket socket = null; + try { + socket = new DatagramSocket(); // Reserve a random port + } catch (Exception e) { + System.err.println("Failed to bind server socket"); + e.printStackTrace(); + } + return socket; + } + private DatagramPacket read(DatagramSocket socket) { byte[] receivedData = new byte[1024]; DatagramPacket receivedPacket = new DatagramPacket( @@ -50,42 +61,32 @@ public class Server { return new Client(packet.getAddress(), packet.getPort()); } - // public void test(String[] args) { - // while (mainServerPortListening) { - // try { - // DatagramSocket socket = new DatagramSocket(); // Reserve new port + private void attributeNewPort(Client client) { + DatagramSocket newSocket = getNewSocket(); + int port = newSocket.getLocalPort(); + String response = "PORT:" + port; + client.setPort(port); - // String response = "PORT:" + socket.getLocalPort(); - // System.out.println(response); - // byte[] envoyees; // tampon d'émission - // envoyees = response.getBytes(); - // DatagramPacket packetToSend = new DatagramPacket( - // envoyees, - // envoyees.length, - // clientAddress, - // clientPort - // ); - // mainServerSocket.send(packetToSend); - // Thread thread = new Thread(() -> createThread(socket)); - // thread.start(); - // } catch (Exception e) { - // System.err.println(e); - // } - // } - - // mainServerSocket.close(); - // } + byte[] sendData; + sendData = response.getBytes(); + DatagramPacket packetToSend = new DatagramPacket( + sendData, + sendData.length, + client.getAddress(), + port + ); + try { + this.mainServerSocket.send(packetToSend); + } catch (IOException e) { + e.printStackTrace(); + } + } public static void run() { System.out.println("Server started"); Server server = new Server(); DatagramPacket packet = server.read(server.mainServerSocket); Client client = server.getClient(packet); - System.out.println( - "Client: " + - client.getClientAddress() + - ":" + - client.getClientPort() - ); + server.attributeNewPort(client); } } From 2459dca82e7f69f7d059aa7f868ee3c07f910f17 Mon Sep 17 00:00:00 2001 From: Xeon0X Date: Tue, 1 Apr 2025 00:00:41 +0200 Subject: [PATCH 4/5] feat: add clients handler via thread --- app/src/main/java/clientserver/App.java | 3 +- .../main/java/clientserver/client/Client.java | 23 ++-- .../clientserver/server/ClientHandler.java | 74 +++++++++++ .../main/java/clientserver/server/Server.java | 121 ++++++++++++------ 4 files changed, 171 insertions(+), 50 deletions(-) create mode 100644 app/src/main/java/clientserver/server/ClientHandler.java diff --git a/app/src/main/java/clientserver/App.java b/app/src/main/java/clientserver/App.java index bc0006c..658a06e 100644 --- a/app/src/main/java/clientserver/App.java +++ b/app/src/main/java/clientserver/App.java @@ -43,7 +43,8 @@ public class App { break; case "server": System.out.println("Starting server..."); - Server.run(); + Server server = new Server(6666); + server.run(); break; } } diff --git a/app/src/main/java/clientserver/client/Client.java b/app/src/main/java/clientserver/client/Client.java index 9a046df..c8cce17 100644 --- a/app/src/main/java/clientserver/client/Client.java +++ b/app/src/main/java/clientserver/client/Client.java @@ -3,6 +3,8 @@ package clientserver.client; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; +import java.util.concurrent.Delayed; +import java.util.concurrent.TimeUnit; public class Client { @@ -64,15 +66,18 @@ public class Client { System.out.println("Connexion au nouveau port: " + newPort); // 4 - Communiquer sur le nouveau port - String messagePort = "Message au nouveau port"; - byte[] envoyeesPort = messagePort.getBytes(); - DatagramPacket paquetPort = new DatagramPacket( - envoyeesPort, - envoyeesPort.length, - adresseServeur, - newPort - ); - socketClient.send(paquetPort); + for (int i = 0; i < 5; i++) { + String messagePort = "Message au nouveau port"; + byte[] envoyeesPort = messagePort.getBytes(); + DatagramPacket paquetPort = new DatagramPacket( + envoyeesPort, + envoyeesPort.length, + adresseServeur, + newPort + ); + socketClient.send(paquetPort); + TimeUnit.SECONDS.sleep(1); + } } // 5 - Libérer le canal diff --git a/app/src/main/java/clientserver/server/ClientHandler.java b/app/src/main/java/clientserver/server/ClientHandler.java new file mode 100644 index 0000000..1d4eca6 --- /dev/null +++ b/app/src/main/java/clientserver/server/ClientHandler.java @@ -0,0 +1,74 @@ +package clientserver.server; + +import clientserver.client.Client; +import java.net.DatagramPacket; +import java.net.DatagramSocket; + +public class ClientHandler implements Runnable { + + private final DatagramSocket socket; + private final Client client; + private boolean running = true; + + public ClientHandler(DatagramSocket socket, Client client) { + this.socket = socket; + this.client = client; + } + + public void stop() { + running = false; + if (socket != null && !socket.isClosed()) { + socket.close(); + } + } + + @Override + public void run() { + System.out.println( + "Started handler for client " + + client.getAddress() + + ":" + + client.getPort() + ); + + // try { + // socket.setSoTimeout(30000); + // } catch (Exception e) { + // System.err.println("Could not set socket timeout"); + // } + + while (running && !socket.isClosed()) { + DatagramPacket packet = Server.receivePacket(socket); + if (packet == null) continue; + + String message = new String( + packet.getData(), + 0, + packet.getLength() + ); + System.out.println( + "Received from " + + client.getAddress() + + ":" + + client.getPort() + + ": " + + message + ); + // Reply with echo + // String response = "ECHO: " + message; + // Server.sendMessage( + // socket, + // response, + // client.getAddress(), + // client.getPort() + // ); + } + + System.out.println( + "Client handler terminated for " + + client.getAddress() + + ":" + + client.getPort() + ); + } +} diff --git a/app/src/main/java/clientserver/server/Server.java b/app/src/main/java/clientserver/server/Server.java index 5d0e8c9..171426d 100644 --- a/app/src/main/java/clientserver/server/Server.java +++ b/app/src/main/java/clientserver/server/Server.java @@ -9,40 +9,35 @@ public class Server { private int mainServerPort; private DatagramSocket mainServerSocket; + private boolean isRunning; public Server(int port) { this.mainServerPort = port; mainServerSocket = createSocket(this.mainServerPort); - } - - public Server() { - this.mainServerPort = 6666; - mainServerSocket = createSocket(this.mainServerPort); + isRunning = true; } private DatagramSocket createSocket(int port) { - DatagramSocket socket = null; try { - socket = new DatagramSocket(port); + return new DatagramSocket(port); } catch (Exception e) { - System.err.println("Failed to bind server socket"); + System.err.println("Failed to bind server socket on port " + port); e.printStackTrace(); + return null; } - return socket; } private DatagramSocket getNewSocket() { - DatagramSocket socket = null; try { - socket = new DatagramSocket(); // Reserve a random port + return new DatagramSocket(); // Reserve a random port } catch (Exception e) { - System.err.println("Failed to bind server socket"); + System.err.println("Failed to create new server socket"); e.printStackTrace(); + return null; } - return socket; } - private DatagramPacket read(DatagramSocket socket) { + public static DatagramPacket receivePacket(DatagramSocket socket) { byte[] receivedData = new byte[1024]; DatagramPacket receivedPacket = new DatagramPacket( receivedData, @@ -51,42 +46,88 @@ public class Server { try { socket.receive(receivedPacket); // Blocking call + return receivedPacket; } catch (IOException e) { e.printStackTrace(); + return null; } - return receivedPacket; } - private Client getClient(DatagramPacket packet) { - return new Client(packet.getAddress(), packet.getPort()); - } - - private void attributeNewPort(Client client) { - DatagramSocket newSocket = getNewSocket(); - int port = newSocket.getLocalPort(); - String response = "PORT:" + port; - client.setPort(port); - - byte[] sendData; - sendData = response.getBytes(); - DatagramPacket packetToSend = new DatagramPacket( - sendData, - sendData.length, - client.getAddress(), - port - ); + public static void sendMessage( + DatagramSocket socket, + String message, + java.net.InetAddress address, + int port + ) { try { - this.mainServerSocket.send(packetToSend); + byte[] sendData = message.getBytes(); + DatagramPacket packetToSend = new DatagramPacket( + sendData, + sendData.length, + address, + port + ); + socket.send(packetToSend); } catch (IOException e) { + System.err.println( + "Failed to send message to " + address + ":" + port + ); e.printStackTrace(); } } - public static void run() { - System.out.println("Server started"); - Server server = new Server(); - DatagramPacket packet = server.read(server.mainServerSocket); - Client client = server.getClient(packet); - server.attributeNewPort(client); + private void handleNewConnection() { + DatagramPacket packet = receivePacket(mainServerSocket); + if (packet == null) return; + + Client client = new Client(packet.getAddress(), packet.getPort()); + + // Log the initial connection request + System.out.println( + "New connection request from " + + client.getAddress() + + ":" + + client.getPort() + ); + + // Process the received message + String message = new String(packet.getData(), 0, packet.getLength()); + System.out.println("Received message: " + message); + + // Create a new socket for this client + DatagramSocket clientSocket = getNewSocket(); + if (clientSocket == null) return; + + int newPort = clientSocket.getLocalPort(); + client.setPort(newPort); + + // Send new port information to client + String response = "PORT:" + newPort; + sendMessage( + mainServerSocket, + response, + client.getAddress(), + packet.getPort() + ); + + // Create and start a ClientHandler for this connection + ClientHandler handler = new ClientHandler(clientSocket, client); + Thread thread = new Thread(handler); + thread.start(); + } + + public void run() { + System.out.println("Server started on port " + mainServerPort); + while (isRunning) { + try { + handleNewConnection(); + } catch (Exception e) { + System.err.println( + "Error handling connection: " + e.getMessage() + ); + e.printStackTrace(); + } + } + System.out.println("Server shutdown"); } } From 18370419969b29164b20f065059d7b8640972738 Mon Sep 17 00:00:00 2001 From: Xeon0X Date: Tue, 1 Apr 2025 00:14:28 +0200 Subject: [PATCH 5/5] fix: names and prints --- .../main/java/clientserver/client/Client.java | 46 +++++++++---------- .../clientserver/server/ClientHandler.java | 2 +- .../main/java/clientserver/server/Server.java | 17 +++++-- 3 files changed, 36 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/clientserver/client/Client.java b/app/src/main/java/clientserver/client/Client.java index c8cce17..05f65d2 100644 --- a/app/src/main/java/clientserver/client/Client.java +++ b/app/src/main/java/clientserver/client/Client.java @@ -3,7 +3,6 @@ package clientserver.client; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; -import java.util.concurrent.Delayed; import java.util.concurrent.TimeUnit; public class Client { @@ -32,50 +31,51 @@ public class Client { try { // 1 - Création du canal avec un port libre DatagramSocket socketClient = new DatagramSocket(); - InetAddress adresseServeur = InetAddress.getByName("localhost"); - int portServeur = 6666; + InetAddress serverAddress = InetAddress.getByName("localhost"); + int serverPort = 6666; // 2 - Envoyer un message au serveur - String message = "Hello Server"; - byte[] envoyees = message.getBytes(); - DatagramPacket paquetEnvoye = new DatagramPacket( - envoyees, - envoyees.length, - adresseServeur, - portServeur + String message = "Connection request"; + byte[] sendData = message.getBytes(); + DatagramPacket sendPacket = new DatagramPacket( + sendData, + sendData.length, + serverAddress, + serverPort ); - socketClient.send(paquetEnvoye); - System.out.println("Message envoyé au serveur"); + socketClient.send(sendPacket); + System.out.println("New connection request sent"); // 3 - Recevoir - byte[] recues = new byte[1024]; // tampon de réception - DatagramPacket paquetRecu = new DatagramPacket( - recues, - recues.length + byte[] receivedData = new byte[1024]; // tampon de réception + DatagramPacket receivedPacket = new DatagramPacket( + receivedData, + receivedData.length ); - socketClient.receive(paquetRecu); + socketClient.receive(receivedPacket); String reponse = new String( - paquetRecu.getData(), + receivedPacket.getData(), 0, - paquetRecu.getLength() + receivedPacket.getLength() ); if (reponse.startsWith("PORT:")) { int newPort = Integer.parseInt(reponse.substring(5)); - System.out.println("Connexion au nouveau port: " + newPort); + System.out.println("Connected on port:" + newPort); // 4 - Communiquer sur le nouveau port - for (int i = 0; i < 5; i++) { - String messagePort = "Message au nouveau port"; + for (int i = 0; i < 20; i++) { + String messagePort = "Test"; byte[] envoyeesPort = messagePort.getBytes(); DatagramPacket paquetPort = new DatagramPacket( envoyeesPort, envoyeesPort.length, - adresseServeur, + serverAddress, newPort ); socketClient.send(paquetPort); + System.out.println("Test sent"); TimeUnit.SECONDS.sleep(1); } } diff --git a/app/src/main/java/clientserver/server/ClientHandler.java b/app/src/main/java/clientserver/server/ClientHandler.java index 1d4eca6..7d959a1 100644 --- a/app/src/main/java/clientserver/server/ClientHandler.java +++ b/app/src/main/java/clientserver/server/ClientHandler.java @@ -38,7 +38,7 @@ public class ClientHandler implements Runnable { // } while (running && !socket.isClosed()) { - DatagramPacket packet = Server.receivePacket(socket); + DatagramPacket packet = Server.receivedPacket(socket); if (packet == null) continue; String message = new String( diff --git a/app/src/main/java/clientserver/server/Server.java b/app/src/main/java/clientserver/server/Server.java index 171426d..ef2f21d 100644 --- a/app/src/main/java/clientserver/server/Server.java +++ b/app/src/main/java/clientserver/server/Server.java @@ -27,7 +27,7 @@ public class Server { } } - private DatagramSocket getNewSocket() { + private DatagramSocket createNewSocket() { try { return new DatagramSocket(); // Reserve a random port } catch (Exception e) { @@ -37,7 +37,7 @@ public class Server { } } - public static DatagramPacket receivePacket(DatagramSocket socket) { + public static DatagramPacket receivedPacket(DatagramSocket socket) { byte[] receivedData = new byte[1024]; DatagramPacket receivedPacket = new DatagramPacket( receivedData, @@ -77,7 +77,7 @@ public class Server { } private void handleNewConnection() { - DatagramPacket packet = receivePacket(mainServerSocket); + DatagramPacket packet = receivedPacket(mainServerSocket); if (packet == null) return; Client client = new Client(packet.getAddress(), packet.getPort()); @@ -92,10 +92,17 @@ public class Server { // Process the received message String message = new String(packet.getData(), 0, packet.getLength()); - System.out.println("Received message: " + message); + System.out.println( + "Received message from " + + client.getAddress() + + ":" + + client.getPort() + + ": " + + message + ); // Create a new socket for this client - DatagramSocket clientSocket = getNewSocket(); + DatagramSocket clientSocket = createNewSocket(); if (clientSocket == null) return; int newPort = clientSocket.getLocalPort();