From 1f52c66270b380d46c7c8a37fb80a609caa3be82 Mon Sep 17 00:00:00 2001 From: Xeon0X Date: Tue, 1 Apr 2025 00:00:41 +0200 Subject: [PATCH] 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"); } }