:: Enseignements :: Master :: Master TTT :: 2010-2011 :: Programmation réseau en Java ::
![[LOGO]](http://igm.univ-mlv.fr/ens/resources/mlv.png) | Client TCP graphique en Java |
Un client TCP utilisant un terminal est peu convivial lorsque des données sont reçues alors que l'utilisateur saisit des données : l'affichage des données reçues est alors désagréablement mélangé avec la saisie de l'utilisateur. Il existe des bibliothèques externes permettant d'obtenir une interface en console de type curses (comme JCurses). Java propose cependant dans son API standard la bibliothèque graphique Swing (javax.swing) que nous utiliserons.
La fenêtre du client comportera une zone de saisie pour l'utilisateur ainsi qu'une zone d'affichage du texte reçu et envoyé (zones implantées à l'aide de JTextArea). Un bouton permettra de valider la saisie. On lancera l'exécution du client par la commande :
java ClientTCPGraphique hote_distant port_distant encodage
Communication à l'aide de file d'attente
Écrire une classe
TCPFileCommunication permettant de communiquer avec le serveur par l'intermédiaire de files d'attente. On pourra utiliser la classe
FileAttente déjà réalisée ou bien employer la classe
ArrayBlockingQueue implantant l'interface
BlockingQueue de l'API Java.
Nous utilisons deux files d'attente :
- Une file pour stocker les messages en attente d'expédition vers le serveur. Une thread recupère les messages en attente pour les envoyer vers la socket distante.
- Une file pour conserver les messages reçus du serveur. Une thread recupère les messages reçus sur la socket locale en provenance de la socket distante.
Interface graphique
Créer une classe CommunicationFenetre héritant de classe javax.swing.JFrame dont le constructeur initialise les composantes graphiques. Le constructeur prendra en arguments les files de messages reçus et en instance d'envoi.
Il est nécessaire maintenant de lier le clic sur le bouton d'envoi à une action de mise en file d'attente d'envoi du message saisi. Nous créons à cet effet un ActionListener que nous enregistrons au bouton :
this.boutonEnvoi.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
this.zoneAffichage.setText(this.zoneAffichage.getText() + "\n" + this.zoneSaisie.getText());
this.fileEnvoi.add(this.zoneSaisie.getText());
this.zoneSaisie.setText(""); // Réinitialisation de la zone de saisie
}
});
Le code exécuté par un Listener suite à la survenue d'un évènement bloque le rafraichissement de l'interface graphique. Dans quel cas ceci pourrait-il poser problème pour le code précédent ? Comment s'en prémunir ?
Le code précédent permet d'ajouter dans la file d'envoi et la zone d'affichage les messages envoyés. Il reste à traiter les messages reçus. Exécuter à cet effet une thread, initialisée à la construction de la fenêtre qui récupère les messages de la file de réception et les ajoute à la zone d'affichage.
Que peut-il se passer lorsqu'un message est envoyé et un autre reçu à peu de temps d'intervalle ? Modifier le code pour gérer cette situation.
Ajouter du code gérant la fermeture propre de la connexion vers la socket cliente à la fermeture de la fenêtre graphique.
Idées d'améliorations
- Pour un affichage plus agréable des messages (avec mise en forme), on pourra manipuler le modèle Document de l'instance de JTextArea.
- On pourra supporter des connexions TCP vers plusieurs serveurs : les messages sont envoyés sur l'ensemble des serveurs et l'on reçoit les messages de tous ces serveurs.
© Université de Marne-la-Vallée