Skip to content

hatch01/arsir

Repository files navigation

TP n°1. Architecture client/serveur

Pour build :

./gradlew build

Pour run l'application principale, qui propose de lancer les clients et serveurs de chaque exercice :

./gradlew run

Exercice 1 : Horloge parlante via TCP

Après avoir build le projet en utilisant ./gralew build, le client et le serveur peuvent également être lancés directement avec :

  • ./gradlew runUDPHorlogeServer
  • ./gradlew runUDPHorlogeClient

Cette tâche, comme toutes les autres, a été définie dans build.gradle.kts.

Faire attention qu'il n'y pas d'autres applications utilisant le même port lancées en même temps. Celui-ci peut également être changé dans UDPHorlogeClient.java et UDPHorlogeServer.java en modiant les constantes respectives. Ces instructions sont valablres pour les autres exercices.

Output

Output côté serveur :

Serveur UDP en attente sur le port 12345
Réponse envoyée au client : 2025-10-09 12:17:22

Ouput côté client :

Requête envoyée au serveur :
Requête reçue du serveur : 2025-10-09 12:17:22
Client fermé

Exercice 2 : Synchronisation réseau

Run :

  • ./gradlew runNTPServer
  • ./gradlew runNTPClient

On utilise UDP ici pour sa rapidité et sa simplicité comparé à TCP. Etant donné le contexte temporel de la synchronisation, le plus rapide le mieux.

Diagramme :

sequenceDiagram
    participant Client
    participant Serveur

    Client->>Serveur: Envoie T1 (heure courante)
    Note right of Serveur: T'_1 = heure de réception
    Serveur-->>Client: Renvoie T1, T'_1, T'_2 (heure d'envoi)
    Note left of Client: T2 = heure de réception

    Client->>Client: Calcule δ = (T2 - T1) - (T'_2 - T'_1)
    Client->>Client: Calcule θ = (T'_1 + T'_2)/2 - (T1 + T2)/2
    Client->>Client: Corrige l'horloge : heure_courante += θ
Loading

Output

Output côté serveur :

Serveur NTP démarré sur le port 12346
Serveur NTP en attente de messages...
Appuyez sur Ctrl+C pour arrêter le serveur
Message NTP reçu du client /127.0.0.1:33858 - T1=1760004937390, T'1=1760004937401
Réponse NTP envoyée - T1=1760004937390, T'1=1760004937401, T'2=1760004937416

Ouput côté client :

Client NTP connecté au serveur localhost:12346
Commandes:
  'sync' - Effectuer une synchronisation NTP
  'quit' - Quitter

Envoi de la requête NTP - T1 = 1760004937390
Réponse NTP reçue - T1=1760004937390, T'1=1760004937401, T'2=1760004937416, T2=1760004937418

=== Résultats de synchronisation NTP ===
Délai de transmission (delta) = 13 ms
Écart entre les horloges (theta) = 4.500 ms
Heure locale avant correction : 1760004937422
Heure corrigée : 1760004937427

Exercice 3 : Horloge parlante via TCP

Run :

  • ./gradlew runTCPTimeServer
  • ./gradlew runTCPTimeClient

Output

Output côté serveur :

Serveur TCP en attente sur le port 12347
Heure envoyée au client 2025-10-09 12:32:29
Connexion fermée.

Ouput côté client :

Connecté au serveur localhost sur le port 12347
Heure reçue du serveur : 2025-10-09 12:32:29
Connexion fermée par le serveur

Exercice 4 : Horloge parlante via TCP

Run :

  • runTCPEnhancedTimeServer
  • runTCPEnhancedTimeClient

Output

Output côté serveur :

Serveur d'horloge parlante TCP démarré sur le port 12348
Serveur en attente de connexions...
Commandes supportées: DATE, HOUR, FULL, CLOSE
Appuyez sur Ctrl+C pour arrêter le serveur
Connexion acceptée de /127.0.0.1:34806
Début de session avec /127.0.0.1:34806
Commande reçue de /127.0.0.1:34806: DATE
Envoyé à /127.0.0.1:34806: Date: 2025-10-09
Commande reçue de /127.0.0.1:34806: HOUR
Envoyé à /127.0.0.1:34806: Heure: 12:46:46
Commande reçue de /127.0.0.1:34806: FULL
Envoyé à /127.0.0.1:34806: Date et heure: 2025-10-09 12:46:48
Commande reçue de /127.0.0.1:34806: CLOSE
Fermeture de connexion demandée par /127.0.0.1:34806
Connexion fermée avec /127.0.0.1:34806

Ouput côté client :

Connecté au serveur localhost:12348
=== Horloge Parlante TCP ===
Commandes disponibles:
  DATE  - Affiche la date
  HOUR  - Affiche l'heure
  FULL  - Affiche date et heure
  CLOSE - Ferme la connexion
Tapez votre commande:

> DATE

Date: 2025-10-09

Exercice 5 : Capitalisation

Run :

  • runCapitalizationServer
  • runCapitalizationClient

Output

Output côté serveur :

Serveur de capitalisation TCP démarré sur le port 12349
Serveur en attente de connexions...
Connexion acceptée de /127.0.0.1:38572
Reçu de /127.0.0.1:38572: test
Envoyé à /127.0.0.1:38572: TEST

Ouput côté client :

Serveur: localhost:12349
Commandes:
  'connect' - Se connecter au serveur
  'quit' - Quitter le client

> connect
Connecté au serveur localhost:12349
=== Serveur de Capitalisation ===
Envoyez vos lignes de texte, elles seront renvoyées en majuscules
Tapez 'QUIT' pour fermer la connexion

> test
Capitalisé: TEST

Exercice 6 : Tic-tac-toe

Q1 :

La class à cette structure :

classDiagram
    class Jeu {
        +char JOUEUR_X
        +char JOUEUR_O
        +char VIDE
        -char[][] grille
        -char joueurCourant
        -boolean partieTerminee
        -char gagnant
        +Jeu()
        +void initialiser()
        +synchronized boolean coupValide(int ligne, int colonne)
        +synchronized boolean jouerCoup(int ligne, int colonne, char joueur)
        -boolean verifierVictoire(char joueur)
        -boolean grillePleine()
        +synchronized String getGrilleString()
        +synchronized char getJoueurCourant()
        +synchronized boolean isPartieTerminee()
        +synchronized char getGagnant()
        +synchronized char getCase(int ligne, int colonne)
    }
Loading

Les états sont stocké dans une grille simplement sous forme de tableau 2D de char. Le test des coup valide est donc simple :

  • Le coup est dans les limites de la grille
  • La case est vide

Q2 :

sequenceDiagram
    participant C1 as Client 1
    participant S as Serveur
    participant C2 as Client 2

    Note over C1,C2: Connexion des joueurs
    C1->>S: Connexion TCP
    S->>C1: BIENVENUE<br/>ATTENTE

    C2->>S: Connexion TCP
    S->>C2: BIENVENUE

    Note over S: Choix aléatoire<br/>qui joue X/O

    S->>C1: DEBUT X
    S->>C2: DEBUT O
    S->>C1: GRILLE (vide)
    S->>C2: GRILLE (vide)

    Note over C1,C2: Partie en cours

    loop Tour de jeu
        S->>C1: VOTRE_TOUR
        C1->>S: COUP ligne colonne
        S->>C1: COUP_VALIDE
        S->>C2: COUP_ADVERSAIRE ligne colonne
        S->>C1: GRILLE (état mis à jour)
        S->>C2: GRILLE (état mis à jour)

        S->>C2: VOTRE_TOUR
        C2->>S: COUP ligne colonne
        S->>C2: COUP_VALIDE
        S->>C1: COUP_ADVERSAIRE ligne colonne
        S->>C1: GRILLE (état mis à jour)
        S->>C2: GRILLE (état mis à jour)
    end

    Note over C1,C2: Fin de partie

    S->>C1: VICTOIRE
    S->>C2: DEFAITE
Loading

Messages du protocole

Serveur → Client
  • BIENVENUE : Connexion acceptée
  • ATTENTE : En attente du second joueur
  • DEBUT X/O : Le symbole attribué est X ou O
  • VOTRE_TOUR : C'est au joueur de jouer
  • COUP_VALIDE : Coup accepté
  • COUP_INVALIDE raison : Coup refusé avec raison (case occupée, hors limites, pas votre tour, partie terminée, format incorrect)
  • COUP_ADVERSAIRE ligne colonne : L'adversaire a joué
  • GRILLE état : État de la grille (9 caractères)
  • VICTOIRE/DEFAITE/MATCH_NUL : Résultat final
  • ADVERSAIRE_DECONNECTE : L'adversaire s'est déconnecté
  • ADVERSAIRE_QUITTE : L'adversaire a abandonné
  • COMMANDE_INCONNUE commande : Commande non reconnue
Client → Serveur
  • COUP ligne colonne : Jouer à la position (0-2, 0-2)
  • QUITTER : Abandonner
  • PRET : Joueur prêt (optionnel)

Q3

classDiagram
    class Thread {
        <<abstract>>
    }

    class Joueur {
        -Socket socket
        -BufferedReader in
        -PrintWriter out
        -char symbole
        -Jeu jeu
        -Joueur adversaire
        -boolean estPret

        +Joueur(Socket socket, Jeu jeu)
        +void run()
        -void traiterMessage(String message)
        -void traiterCoup(int ligne, int colonne)
        -void gererFinPartie()
        -String getGrilleEnLigne()
        +void envoyerMessage(String message)
        -void fermerConnexion()
        +char getSymbole()
        +void setSymbole(char symbole)
        +void setAdversaire(Joueur adversaire)
        +boolean isEstPret()
    }

    Thread <|-- Joueur : extends
Loading
# Terminal 1 - Premier joueur
$ nc localhost 12345
BIENVENUE
ATTENTE

# Terminal 2 - Second joueur
$ nc localhost 12345
BIENVENUE
...

Q4

classDiagram
    class Serveur {
        -static final int PORT = 12345
        -ServerSocket serverSocket
        -Jeu jeu
        -Joueur joueur1
        -Joueur joueur2

        +Serveur() throws IOException
        +static void main(String[] args)
        +void demarrer()
        +void arreter()
    }
Loading

Q5

classDiagram
    class Client {
        -static final String SERVER_HOST = "localhost"
        -static final int SERVER_PORT = 12345
        -Socket socket
        -BufferedReader in
        -PrintWriter out
        -char monSymbole
        -char[][] grille
        -boolean monTour
        -boolean partieEnCours

        +Client()
        +static void main(String[] args)
        -void initialiserGrille()
        +void connecter() throws IOException
        -void recevoirMessages()
        -void lireCommandes()
        -void traiterMessageServeur(String message)
        -void mettreAJourGrille(String etat)
        -void afficherGrille()
        +void fermer()
    }
Loading

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •