Développer une application réseau en Java de A à Z

Julien Plu

Nous allons ici voir un article sur le développement de chaque étape d'un système de tchat client/serveur, c'est-à-dire cahier des charges, protocole, étude, conception et enfin développement. Nous baptiserons le protocole de cette application PCU (Protocole de Chat Universitaire). Nous allons d'abord faire un programme de base et ensuite lui apporter des améliorations petit à petit. Commentez cet article : Commentez

- Titre : Développer une application réseau en Java de A à Z

- Auteur : Julien Plu

- Parution : 9 juin 2010

- Mise à jour : 10 juin 2010

- Public visé :

- Licence : Copyright ® 2010-2013 Julien Plu. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Cahier des charges

- I-A. Programme de base

- I-A-1. Administration

- I-A-2. Canal de discussion

- I-A-3. Discussions privées (pv)

- I-A-4. Transfert de fichiers

- I-A-5. Protocole

- I-A-6. Sécurité

- I-B. Programme amélioré

- II. Protocole

- II-A. Introduction

- II-B. Spécifications

- II-B-1. Généralités

- II-B-2. Messages

- II-B-3. Conventions

- II-B-4. Format des messages en pseudoBNF

- II-C. États

- II-C-1. Non authentifié

- II-C-2. Authentifié

- II-C-3. Connecté à un canal

- II-C-4. Connexion directe

- II-D. Messages

- II-D-1. Enregistrement de la connexion

- II-D-1-a. IDENTIFIER

- II-D-1-b. QUITTER

- II-D-1-c. FINCONNEXION

- II-D-2. Opérations sur les canaux

- II-D-2-a. REJOINDRE

- II-D-2-b. MESSAGE

- II-D-2-c. MEMBRE

- II-D-2-d. QUITTERCANAL

- II-D-2-e. NOTIFIER

- II-D-3. Connexion directe

- II-D-3-a. CONNEXIONDIRECTE

- II-D-3-b. MESSAGEPRIVE

- II-D-3-c. TRANSFERTFICHIER

- II-D-4. Informations

- II-D-4-a. LISTER

- II-D-4-b. INFOMEMBRE

- II-D-4-c. MOTD

- II-D-5. Administration

- II-D-5-a. CNL_CREER

- II-D-5-b. CNL_SUPPRIMER

- II-D-5-c. CNL_CHANGERSUJET

- II-D-5-d. UTL_EJECTER

- II-D-5-e. UTL_BANNIR

- II-D-5-f. SRV_RELANCER

- II-D-5-g. SRV_STOPPER

- II-D-5-h. SRV_LISTER

- III. Spécifications

- III-A. Mode d'administration

- III-B. Serveur.conf

- III-C. Base de données

- III-D. Fichiers de logs

- IV. Conception

- V. Annexe

- VI. Remerciements

I - Cahier des charges

Ce projet est né lorsque je me suis rendu compte qu'à l'université nous ne pouvions pas communiquer par MSN/IRC/Jabber ou autre, j'ai donc décidé de faire un système de tchat pour que tout le monde puisse se parler aussi bien sur le réseau de l'université qu'ailleurs. J'ai également décidé de développer un site un minimum communautaire autour de ce logiciel de tchat afin que tous les élèves puissent partager ce qu'ils veulent et quand ils le veulent et aussi leur faciliter l'accès aux ressources mises à disposition par l'université.
Nous allons donc voir comment le projet a été conçu de A à Z.

I-A - Programme de base

I-A-1 - Administration

Le serveur est administré par une ou plusieurs personnes à partir du client, celle-ci peut :

- créer, supprimer un canal et changer le sujet d'un canal ;

- éjecter un utilisateur d'un canal et bannir un utilisateur du serveur.

I-A-2 - Canal de discussion

Un canal de discussion rassemble plusieurs clients qui discutent tous dans le même espace. Il se distingue par son nom, son sujet et sa liste d'utilisateurs. Seul l'administrateur du serveur peut créer de nouveaux canaux.

I-A-3 - Discussions privées (pv)

Si deux utilisateurs souhaitent s'entretenir en dehors d'un canal, le serveur les met en relation directe de façon à ce qu'ils puissent communiquer sans que les messages transitent par celui-ci. L'invitation à une discussion privée peut être déclinée.

I-A-4 - Transfert de fichiers

Deux utilisateurs peuvent échanger des fichiers. Pour cela ils ne passent pas par le serveur pour des raisons d'efficacité. De même que pour les discussions privées, un transfert de fichier peut être refusé par l'un des utilisateurs.

I-A-5 - Protocole

Nous allons mettre en place un protocole pur texte avec l'encodage UTF-8.

I-A-6 - Sécurité

Chaque utilisateur doit être authentifié (login/password) pour pouvoir accéder aux fonctionnalités du serveur. Pour l'authentification, une base de données stockera les identifiants et les mots de passe de chaque utilisateur. L'inscription se fera sur un site web (partie que nous ne verrons pas dans cet article ou bien alors bien plus tard).

I-B - Programme amélioré

Je vais lister ici certaines possibilités d'amélioration du programme :

- comptes modérateurs ;

- la connexion client/serveur est chiffrée à l'aide de SSL/TLS ;

- émoticônes ;

- coloration syntaxique ;

- ajout d'un bot ;

- canaux de quizz ;

- ajout de module par scripting ;

- gestion des statuts.

II - Protocole

Nous allons ici détailler le protocole utilisé.

II-A - Introduction

On appelle serveur l'hôte fournissant le service, et client l'hôte l'utilisant. Le Protocole PCU fournit un service de discussion instantanée et de mise en relation entre clients, construit sur le protocole TCP/IP, il est volontairement écrit entièrement en français. Il s'organise autour de deux fonctionnalités principales :

- les discussions plusieurs-à-plusieurs, par canaux ;

- les discussions un-à-un, en connexion directe, qui prend également en charge les transferts de fichiers.

Un canal est un groupe nommé d'un ou plusieurs clients qui recevront tous les messages adressés à ce canal. On appelle connexion directe une connexion entre deux clients ne passant pas par le serveur.

II-B - Spécifications

II-B-1 - Généralités

Pour être indépendant de tout langage, PCU est un protocole pur texte, et afin d'être compatible avec la majeure partie des caractères existants l'encodage utilisé est UTF-8.

II-B-2 - Messages

Les messages échangés utilisent :

- SP (0x20) et CR (0x0D) comme séparateur ;

- CRLF (0x0D, 0x0A) comme séquence de terminaison ;

- LF (0x0A) comme caractère de fin de ligne.

Les réponses du serveur doivent permettre au client de savoir à quel message il répond. Si un client fait une demande du nombre de connectés, des réponses simples comme +OK_REQUETE ou -ERR_ERREUR seront renvoyées par le serveur.

II-B-3 - Conventions

Le nom des commandes est volontairement long de façon à être le plus explicite possible. Le format des commandes est défini ci-dessous.

Convention des réponses :

1. + préfixe une réponse n'étant pas une erreur et est suivi de :

1. OK pour une réponse positive,

2. KO pour une réponse négative ;

2. - préfixe une erreur et est toujours suivi de ERR.

II-B-4 - Format des messages en pseudoBNF

Format des messages émis par le client :

- REQUETE ::= <COMMANDE><sp> | <cr>[<PARAMS>]<crlf> ;

- COMMANDE ::= un message ;

- PARAMS ::= chaîne UTF-8 séparée par des SP.

Format des messages émis par le serveur :

- REPONSE ::= <PREFIXE> <TEXTE><crlf> ;

- PREFIXE ::= (+<SUCCES> | -<ERREUR> | ) ;

- SUCCES ::= (OK|KO)_<COMMANDE> ;

- ERREUR ::= chaîne alphabétique en majuscules, sans espace, préfixée par ERR_ ;

- TEXTE ::= chaîne alphabétique.

II-C - États

II-C-1 - Non authentifié

État de la connexion client/serveur avant la réussite de l'authentification du client.

II-C-2 - Authentifié

État de la connexion après la réussite de l'authentification.

II-C-3 - Connecté à un canal

État de la connexion client/serveur après la connexion à un canal.

II-C-4 - Connexion directe

État de la connexion client/client une fois la connexion directe acceptée par les deux parties.

II-D - Messages

Si un client envoie un message incorrect, c'est-à-dire que les arguments ne correspondent pas à la commande, le serveur lui répond par -ERR_SYNTAXE. Si la commande est inconnue : -ERR_CMDINCONNUE. Si la commande ne peut être invoquée avec l'état courant du client : -ERR_ETAT.

II-D-1 - Enregistrement de la connexion

II-D-1-a - IDENTIFIER

1. Synopsis :

1. IDENTIFIER <login> <mot de passe>

2. Contraintes :

1. Ce message ne peut être émis que dans un état Non authentifié.

3. Description :

1. Le client utilise cette commande pour s'identifier, il passe ainsi dans un état Authentifié. Si l'authentification a réussi, le serveur précise son login et ses droits (admin ou nonadmin).

4. Réponses possibles :

1. L'authentification a réussi :

1. +OK_IDENTIFIER <login> <droits>

2. Le login ou le mot de passe est incorrect :

1. -ERR_ECHECIDENT <login>

3. Le serveur ne peut pas répondre à cette requête à cause d'un problème interne :

1. -ERR_INTERNE

II-D-1-b - QUITTER

1. Synopsis :

1. QUITTER [<message de départ>]

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié.

3. Description :

1. Commande utilisée par le client pour fermer la connexion.

4. Réponses possibles :

1. Aucune

II-D-1-c - FINCONNEXION

1. Synopsis :

1. FINCONNEXION [« <message de départ> »]

2. Contraintes :

1. Message envoyé par le serveur pour prévenir le client de la fin de la connexion lorsque le serveur est stoppé ou relancé, lorsque le nombre maximum de connexions est atteint et enfin lorsqu'un client est banni. Il est possible de préciser un message de fin.

3. Réponses possibles :

1. Aucune

II-D-2 - Opérations sur les canaux

II-D-2-a - REJOINDRE

1. Synopsis :

1. REJOINDRE <nom-canal>

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié.

3. Description :

1. Commande utilisée pour rejoindre un canal.

4. Réponses possibles :

1. Le canal a bien été rejoint :

1. +OK_REJOINDRE <nom-canal>

2. Le client est déjà connecté :

1. -ERR_DEJACONNECTE <nom-canal>

3. Le canal n'existe pas :

1. -ERR_CANALINTROUVABLE <nom-canal>

II-D-2-b - MESSAGE

1. Synopsis :

1. MESSAGE <nom-canal> <texte>

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié et Connecté à un canal.

3. Description :

1. Commande utilisée pour envoyer un message sur un canal.

4. Réponses possibles :

1. Le message a bien été envoyé :

1. +OK_MESSAGE <nom-canal>

2. L'utilisateur n'est pas connecté au canal précisé :

1. -ERR_NONCONNECTE <nom-canal>

3. Le canal n'existe pas :

1. -ERR_CANALINTROUVABLE <nom-canal>

II-D-2-c - MEMBRE

1. Synopsis :

1. MEMBRE <nom-canal>

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié.

3. Description :

1. Commande utilisée pour connaître la liste des connectés au canal.

4. Réponses possibles :

1. Les utilisateurs ont été trouvés :

1. +OK_MEMBRE <nom-canal><CR><login1 login2 … loginN>

2. Le canal n'existe pas :

1. -ERR_CANALINTROUVABLE <nom-canal>

II-D-2-d - QUITTERCANAL

1. Synopsis :

1. QUITTERCANAL <nom-canal>

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié et Connecté à un canal.

3. Description :

1. Commande utilisée pour quitter un canal.

4. Réponses possibles :

1. La déconnexion au canal s'est bien passée :

1. +OK_QUITTERCANAL <nom-canal>

2. L'utilisateur n'est pas connecté au canal précisé :

1. -ERR_NONCONNECTE <nom-canal>

3. Le canal n'exsite pas :

1. -ERR_CANALINTROUVABLE <nom-canal>

II-D-2-e - NOTIFIER

1. Synopsis :

1. NOTIFIER <nom-canal> <evenement> ([<login>] | [<login>] [« <texte> »] | [« <texte> »])

2. Contraintes :

1. Aucunes, ce message est envoyé par le serveur.

3. Description :

1. Ce message est envoyé par le serveur aux clients connectés à un canal pour les notifier d'un évènement affectant le canal.

4. Il y a six évènements possibles :

1. REJOINT <login>

2. PARLE <login> « <texte> »

3. PARTI <login>

4. EJECTE <login>

5. SUJETCHANGE « <texte> »

6. SUPPRIME

7. BANNI <login>

II-D-3 - Connexion directe

II-D-3-a - CONNEXIONDIRECTE

1. Synopsis :

1. CONNEXIONDIRECTE <login> <IP>

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié.

3. Description :

1. Commande utilisée par un client A pour demander une connexion directe à un autre client B. Le serveur sert d'intermédiaire, et permet aux deux clients de s'échanger les informations nécessaires comme leurs adresses IP respectives, et le port sur lequel la connexion doit se faire. On distingue quatre étapes :

4. Réponses possibles de la part du serveur :

1. Le login est introuvable :

1. -ERR_LOGININTROUVABLE <login>

5. Réponses possibles de la part de B :

1. Confirmation de la connexion directe. Avant l'envoi de cette réponse, il se met en écoute :

1. +OK_CONNEXIONDIRECTE <IP> <port>

2. Refus de la connexion :

1. +KO_CONNEXIONDIRECTE <login>

II-D-3-b - MESSAGEPRIVE

1. Synopsis :

1. MESSAGEPRIVE <texte>

2. Contraintes :

1. Ce message ne peut être émis que dans un état Connexion directe.

3. Description :

1. Commande utilisée dans le cadre d'une connexion client/client pour envoyer un message.

II-D-3-c - TRANSFERTFICHIER

1. Synopsis :

1. TRANSFERTFICHIER <nom-fichier>

2. Contraintes :

1. Ce message ne peut être émis que dans un état Connexion directe.

3. Description :

1. Cette commande est utilisée pour demander un transfert de fichier. Le client qui propose le transfert précise le nom du fichier. Le receveur lui, précise le port sur lequel il attend la connexion si le transfert est accepté.

4. Réponses possibles :

1. Transfert accepté :

1. +OK_TRANSFERTFICHIER <port>

2. Transfert refusé :

1. +KO_TRANFERTFICHIER

II-D-4 - Informations

II-D-4-a - LISTER

1. Synopsis :

1. LISTER [<nom-canal>]

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié.

3. Description :

1. Commande utilisée pour connaître la liste des canaux du serveur. Le serveur répond par une liste de triplés <nom-canal> <topic> <nombre d'utilisateurs> séparés par CR. Si le nom d'un canal est précisé celle-ci ne s'effectue que sur ce dernier c'est-à-dire que le serveur répond par le triplé <nom-canal> <topic> <nombre d'utilisateurs>

4. Réponses possibles :

1. La liste a été trouvée :

1. +OK_LISTER<CR>triplet1<CR>triplet2<CR>…<CR>tripletN

2. Si le nom du canal a été précisé et que celui-ci n'existe pas :

1. -ERR_CANALINTROUVABLE <nom-canal>

II-D-4-b - INFOMEMBRE

1. Synopsis :

1. INFOMEMBRE <login>

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié.

3. Description :

1. Commande utilisée pour connaître les informations relatives à un utilisateur.

4. Réponses possibles :

1. L'utilisateur a été trouvé :

1. +OK_INFOMEMBRE <login><CR>nom-canal1 … nom-canalN

2. L'utilisateur n'a pas été trouvé :

1. -ERR_LOGININTROUVABLE <login>

II-D-4-c - MOTD

1. Synopsis :

1. MOTD

2. Contraintes :

1. Aucunes.

3. Description :

1. Commande utilisée pour connaître le MOTD (Message Of The Day) du serveur.

4. Réponses possibles :

1. Le message est trouvé :

1. +OK_MOTD « <motd> »

2. Une erreur interne est survenue :

1. -ERR_INTERNE

II-D-5 - Administration

Ces commandes sont réservées à l'administrateur. Tout utilisateur non privilégié qui tenterait d'utiliser ces commandes reçoit le message d'erreur -ERR_NONADMINISTRATEUR.

II-D-5-a - CNL_CREER

1. Synopsis :

1. CNL_CREER <nom-canal> « <sujet-canal> »

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié.

3. Description :

1. Création d'un canal.

4. Réponses possibles :

1. Le canal a bien été créé :

1. +OK_CNL_CREER <nom-canal> « <sujet-canal> »

2. Le canal existe déjà :

1. -ERR_CANALEXISTANT <nom-canal>

3. Trop de canaux ont déjà été créés :

1. -ERR_NBCANAUXMAX

II-D-5-b - CNL_SUPPRIMER

1. Synopsis :

1. CNL_SUPPRIMER <nom-canal>

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié.

3. Description :

1. Suppression d'un canal.

4. Réponses possibles :

1. Le canal a bien été supprimé :

1. +OK_CNL_SUPPRIMER <nom-canal>

2. Le canal passé en argument n'existe pas :

1. -ERR_CANALINTROUVABLE <nom-canal>

II-D-5-c - CNL_CHANGERSUJET

1. Synopsis :

1. CNL_CHANGERSUJET <nom-canal> « <nouveau-sujet> »

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié.

3. Description :

1. Commande utilisée pour changer le sujet d'un canal.

4. Réponses possibles :

1. Le sujet du canal a bien été changé :

1. +OK_CNL_CHANGERSUJET <nom-canal> « <nouveau-sujet> »

2. Le canal passé en argument n'existe pas :

1. -ERR_CANALINTROUVABLE <nom-canal>

3. Le sujet n'est pas valide :

1. -ERR_SUJETINCORRECT « <nouveau sujet> »

II-D-5-d - UTL_EJECTER

1. Synopsis :

1. UTL_EJECTER <login> <nom-canal>

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié.

3. Description :

1. Commande utilisée pour éjecter un utilisateur d'un canal.

4. Réponses possibles :

1. L'utilisateur a été éjecté :

1. +OK_UTL_EJECTER <login> <nom-canal>

2. L'utilisateur n'a pas été trouvé sur le serveur :

1. -ERR_LOGININTROUVABLE <login>

3. L'utilisateur n'est pas connecté au canal :

1. -ERR_NONCONNECTE <login> <nom-canal>

4. Le canal n'existe pas :

1. -ERR_CANALINTROUVABLE <nom-canal>

II-D-5-e - UTL_BANNIR

1. Synopsis :

1. UTL_BANNIR <login>

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié.

3. Description :

1. Commande utilisée pour bannir un utilisateur du serveur.

4. Réponses possibles :

1. L'utilisateur a été banni :

1. +OK_UTL_BANNIR <login>

2. L'utilisateur n'a pas été trouvé sur le serveur :

1. -ERR_LOGININTROUVABLE <login>

II-D-5-f - SRV_RELANCER

1. Synopsis :

1. SRV_RELANCER [<message>]

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié.

3. Description :

1. Relance le serveur. Il est possible de préciser un message de notification à l'attention des clients.

4. Réponses possibles :

1. Le serveur va se relancer :

1. FINCONNEXION [<message>]

II-D-5-g - SRV_STOPPER

1. Synopsis :

1. SRV_STOPPER [<message>]

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié.

3. Description :

1. Arrête le serveur. Il est possible de préciser un message de notification à l'attention des clients.

4. Réponses possibles :

1. Le serveur va s'arrêter :

1. FINCONNEXION [<message>]

II-D-5-h - SRV_LISTER

1. Synopsis :

1. SRV_LISTER

2. Contraintes :

1. Ce message ne peut être émis que dans un état Authentifié.

3. Description :

1. Liste toutes les connexions du serveur. Le serveur répond par une liste de couple <login> <IP> séparés par des CR.

4. Réponses possibles :

1. La liste a été trouvée :

1. +OK_SRV_LISTER <CR>liste-connexion

III - Spécifications

III-A - Mode d'administration

Le serveur se lance en 'daemon', sans interface. L'administrateur se connecte avec un client, et le serveur lui donne les droits d'administration lors de l'authentification.

III-B - Serveur.conf

Ce fichier codé entièrement en UTF-8 contient les paramètres de configuration du serveur. Son format est très simple :

1. PROPRIETE1=VALEUR<CRLF>

2. PROPRIETE2=« TEXTE »<CRLF>

3. PROPRIETE3="TEXTE \\

4. SUITE TEXTE %d %ip %nc %nu"

5. …

6. PROPRIETEN=VALEUR<CRLF>

Si le premier caractère non blanc (c'est-à-dire différent de SP, HT …) est #, la suite de la ligne est un commentaire, ignorée lors de la lecture du fichier. Seul le MOTD peut être sur plusieurs lignes à condition qu'une ligne se termine par \\. Le MOTD peut aussi être formaté par les formats suivants :

- %d : date du jour ;

- %ip : adresse IP du serveur ;

- %nu : nombre de clients connectés ;

- %nc : nombre de canaux créés.

Ainsi que la liste des propriétés :

- PORT_ECOUTE ;

- CONNEXION_MAX ;

- CANAUX_MAX ;

- MOTD ;

- MSG_CONNEXION_MAX ;

- MSG_UTL_BANNI ;

- SERVEUR_BDD ;

- PORT_SERVEUR_BDD ;

- NOM_BDD ;

- USER_BDD ;

- MDP_BDD.

III-C - Base de données

La base de données est composée d'une table « utilisateurs » et de six champs :

- (VARCHAR)identifiant : login du client ;

- (VARCHAR MD5)mdp : mot de passe du client ;

- (ENUM)droits : si le client est administrateur ou non ;

- (VARCHAR)mail : l'adresse mail du client ;

- (DATE)inscription : date de l'inscription du client ;

- (ENUM)active : si le client est banni ou non.

III-D - Fichiers de logs

Le serveur produira trois fichiers de logs :

- un pour les connexions / déconnexions ;

- un pour les canaux ;

- un pour le serveur lui-même (lancement, arrêt, problèmes internes…).

IV - Conception

Voici le diagramme UML de l'application telle que je l'ai conçue. Cette façon n'est sans doute pas la meilleure, mais elle fonctionne bien. Si jamais vous avez une meilleure conception, n'hésitez pas à m'en faire part.

Diagramme UML du serveur

V - Annexe

Vous pourrez retrouver l'avancement du projet PCU à cette adresse Donc si vous désirez apporter des idées, rapporter des bogues si vous l'avez testé ou tout autre type de remarque n'hésitez surtout pas à les faire sur le site du projet indiqué ci-dessus.

VI - Remerciements

Merci à Ricky81 ainsi qu'à Baptiste Wicht pour leur aide à la rédaction de cet article. Et merci à Benj. pour sa relecture et correction orthographique.