Accueil Conception Java .NET Dv. Web EDI Langages SGBD Office Solutions d'entreprise Applications Systmes
Java
FORUMS JAVA FAQs JAVA
Spring
Android
Eclipse
NetBeans
BLOG DISCUSSIONS
TUTORIELS JAVA
JAVASEARCH
SOURCES TV
LIVRES
1. Introduction
Dans ce tutoriel, vous allez apprendre tout ce qu'il faut savoir pour dbuter en programmation rseau. Vous allez apprendre ce que sont les sockets et comment les manipuler, vous allez dcouvrir la cration d'un client et celle d'un serveur.
2. Le client
2.A. Introduction
Dans cette partie, nous allons maintenant traiter de la conception et la cration d'un client en rseau avec les sockets. On va apprendre ce que sont les sockets, leur utilit et comment les utiliser, on va aussi apprendre envoyer un mail avec lesdits sockets.
Comme vous le voyez, le constructeur du Socket attend deux arguments: une chane de caractres et un entier. Le premier argument dfinit l'adresse IP du serveur sur lequel nous dsirons nous connecter. Cette adresse peut prendre la forme classique X.X.X.X (par exemple 127.0.0.1 pour votre propre machine) ou vous pouvez utiliser un nom (localhost est quivalent 127.0.0.1). Le deuxime argument permet de dfinir le port sur lequel nous allons nous connecter. En effet, une mme machine est tout fait susceptible d'hberger plusieurs serveurs logiciels. Un serveur Web type proposera ainsi un serveur Telnet, un serveur de mail et un serveur Web (voire un serveur FTP). Or, tous ces serveurs utilisent la mme adresse IP. Il nous faut donc les distinguer, et c'est l que le numro de port intervient. Celui-ci est un nombre positif pouvant prendre n'importe quelle valeur. Cependant, quelques numros sont "rservs": 25 pour le protocole SMTP (envoi
pouvant prendre n'importe quelle valeur. Cependant, quelques numros sont "rservs": 25 pour le protocole SMTP (envoi de mails), 23 pour le Telnet, 8080 pour le protocole HTTP (serveur Web)... Notre but tant de pouvoir envoyer des mails, nous spcifierons donc le port 25 par dfaut.
Par la suite, nous admettrons que tout le code source sera tap dans le bloc try/catch. Si tout s'est bien pass lors de la connexion, la mthode sendMail() retourne la valeur vraie. Sinon, la valeur fausse est retourne. Nous ferons grand usage de ceci par la suite, lors de la lecture des rponses du serveur. Maintenant, nous avons besoin de rcuprer les flux permettant l'change d'informations. Les donnes tant sous forme de texte, nous allons encapsuler les flux dans les objets BufferedReader et OutputStreamWriter du package java.io qui nous faciliteront la tche. Le code rajouter est:
BufferedReader in = new BufferedReader(new InputStreamReader(smtpPipe.getInputStream())); OutputStreamWriter out = new OutputStreamWriter(smtpPipe.getOutputStream()); if (in == null || out == null) return false;
Ds lors, un simple appel de in.readLine() permettra de recevoir une ligne depuis le serveur et out.write(String + "\r\n") permettra d'envoyer des donnes. Nous sommes connects, flux prts servir, il ne nous reste plus qu' suivre le protocole SMTP pas pas:
[lecture] [envoyer: [envoyer: [envoyer: [envoyer: [envoyer: [envoyer: [envoyer: [envoyer:
HELO nom de la machine de l'expditeur] MAIL FROM:<expditeur>] RCPT TO:<destinataire>] DATA] en tte] corps du mail] .] QUIT]
A noter qu'aprs chaque envoi, nous faisons galement une lecture. En effet, chaque tape effectue provoque l'envoi d'une rponse de la part du serveur indiquant si l'on peut continuer ou non. Voici le code type d'une tape:
command = "MAIL FROM:<" + sender + ">"; out.write(command + "\r\n"); out.flush(); trace(command); trace(response = in.readLine()); if (!response.startsWith("250")) return error("Expditeur inconnu");
Ce bout de code correspond l'tape d'identification auprs du serveur. Ici command et response sont deux objets String utiliss tout au long de l'envoi. La premire ligne cre le message envoyer au serveur. Les deux suivantes servent effectuer l'envoi (flush() permettant de "vider" le flux pour s'assurer que tout a t envoy). Ensuite les mthodes trace() permettent d'afficher notre dialogue avec le serveur. Notez que lors du second appel de trace() nous lisons une ligne depuis le flux d'entre. Ensuite, cette ligne est vrifie. A ce stade, si la rponse du serveur ne commence pas par "250", le serveur a rejet l'expditeur. Par exemple, si vous avez utilis une adresse e-mail ne portant pas le mme nom de domaine que le serveur (ne marche que sur smtp.free.fr). Pour suivre en dtail chaque tape, reportez vous au code source du logiciel "Login Mailer" disponible la fin de cet article. Celui-ci est suffisamment document pour que vous puissiez saisir aisment le fonctionnement de la mthode sendMail(). Il convient tout de mme de faire attention la dernire tape de l'envoi de mail. Vous noterez que l'on envoie un simple point (".") pour signifier que l'on a termin. Mais que se passera-t il si le corps du mail contient une ligne avec pour seul texte, un point ? La connexion sera close par le serveur. Le protocole SMTP offre cependant un moyen de remdier cela en envoyant un point d'exclamation la place. Ici encore, reportez vous au code source de l'application LoginMail.
extrmement exigeants en termes de vitesse de rception et d'envoi. Dans ce genre de cas, il ne faut surtout pas utiliser des Strings mais plutt des entiers (type int) voir des primitifs de type byte. Si vous vous retrouvez dans cette situation, conservez tout simplement les flux de base du Socket que vous rcuprerez ainsi:
InputStream in = socket.getInputStream(); OutputStream out = socket.getOutputStream();
L'utilisation conjointe des mthodes read() (qui renvoie un entier) et write(byte) couvriront alors tous vos besoins.
2.E. Screenshots
Telnet...
...mails...
...chat...
3. Le serveur
3.A. Introduction
Chose promise, chose due. Les arcanes des sockets clients n'ayant plus de secrets pour nous, il ne nous reste plus qu' apprendre comment programmer nous mmes ces fameux serveurs sur lesquels nous connections nos logiciels clients. Avant d'aborder l'aspect technique du sujet, intressons nous tout d'abord au fonctionnement gnral d'un serveur logiciel. Nous savons que les clients contiennent des routines ouvrant une connexion sur le port d'un serveur pour y demander et rcuprer des informations. Un serveur logiciel aura donc pour but d'ouvrir un port sur la machine hte et de grer tous les clients se connectant ce port. Cette gestion peut varier d'un type de serveur un autre: simple rponse (un serveur HTTP), distribution aux autres clients (par exemple pour un jeu), mise en relation directe des clients (ICQ ou IRC en mode DCC), et ainsi de suite...
Comme vous pouvez le constater, le constructeur du ServerSocket n'attend qu'un seul et unique argument: un entier. Cet entier joue un peu le mme rle que pour les sockets simples. Il permet de spcifier un port. Mais dans ce cas, cet entier dfinira le numro d'identification du port crer. Vous tes par ailleurs entirement libre du choix du numro du port ds lors que celui-ci est compris dans les limites permises par le type int (de 0 2 147 483 647, c'est dire 2 ^ 32 / 2 - 1 car nous ne pouvons utiliser que des entiers). Toutes les applications rseaux utilisant des ports spcifiques, il vous faudra faire attention ne pas utiliser de numro dj pris. Si votre serveur est destin tre utilis sur une machine personnelle, il est peu probable que l'utilisation des ports 25 (envoi de mails) ou 8080 (HTTP) soit gnante. Cependant, ceci est vivement dconseill, surtout tant donn que la plage de valeurs alloue est largement suffisante pour que vous puissiez y trouver votre bonheur. Dans notre exemple, nous utiliserons le port numro 1705. Afin d'illustrer cet article, nous allons concevoir un logiciel permettant de rpondre des questionnaires simples via un rseau. Ces questionnaires seront une succession de questions choix multiples pour lesquelles chaque bonne rponse donnera un point. Le logiciel se nomme LoginQuiz et se trouve dans les sources disponibles la fin de l'article. La particularit de LoginQuiz est d'utiliser le format XML pour la dfinition de ses questionnaires. Une grande partie du code est ainsi propre la cration des questionnaires depuis des fichiers XML. Nous n'aborderons pas cet aspect de LoginQuiz mais sachez que les fichiers Answer.java, Question.java, QuestionSetHandler.java et QuestionSetReader.java sont ddis cette tche. Toute la partie rseau de notre application est facilite, comme nous allons le voir, par l'utilisation d'une API nomme Caffeine.
Hormis l'encodage de la question, notre "protocole" est vraiment trs simple. L'intrt de sparer chaque rponse par le caractre # permettra au client de les sparer trs facilement en utilisant l'objet java.util.StringTokenizer. Penchons nous maintenant sur le coeur du serveur qui est inscrit dans le fichier QuestionSetServer.java. La cration du serveur passe par le constructeur CaffeineServer(int port, String nom, String motDePasse, int nombreConnexionsMax) de la classe parente. Ici, nous utilisons donc le port 1705, n'utilisons pas de mot de passe et dfinissons 25 comme tant le nombre maximum de clients. La seule autre particularit de cette classe est la mthode serverEvent(ServerEvent evt) appel chaque rception de donnes. Nous allons maintenant laisser un instant cette classe pour regarder de plus prs la fameuse CaffeineServer.
L'instanciation d'un socket serveur est trs simple et demande une seule ligne de code. La deuxime ligne permet de dfinir un dlai au bout duquel une tentative de lecture des sockets connects est considre comme un chec. Cela pour viter de bloquer le serveur en cas de problmes de transmission. Vous constaterez galement que lors de la cration d'un serveur, une exception peut tre rencontre, auquel cas nous arrtons tout. La suite de la mthode startServer() n'offre que peu d'intrt si ce n'est de montrer de quelle manire est-il possible de connatre l'adresse IP de la machine. La seconde mthode, getClient() est place dans la boucle d'un thread et attend tout simplement que quelqu'un daigne bien tenter de se connecter au serveur:
client = server.accept(); new Authorizer(client, password);
Ces deux lignes font tout le travail. L'appel server.accept() va effectivement attendre qu'un client se connecte. Si tel est le cas, nous rcuprons alors un objet Socket. Ensuite, nous crons un nouvel objet Authorizer. Cet objet un peu spcial est une classe interne de CaffeineServer. Cette classe va dmarrer un thread qui se chargera d'administrer la demande de connexion. L'usage d'un thread permet d'viter au serveur de bloquer les demandes des autres clients en attendant la rsolution de la demande en cours. Comme nous n'utilisons pas de mot de passe, la seule partie d'Authorizer qui nous est utile est la suivante:
addClient(new CaffeineSocket(CaffeineServer.this, client));
Ce code va simplement crer un nouvel objet CaffeineSocket et l'ajouter notre liste de clients. CaffeineSocket est un objet grant entirement les Socket clients. En effet, cette classe va crer, de la mme manire que nous l'avions fait pour notre expditeur de mails, des flux d'E/S pour faciliter la communication avec le client. Cet objet cre aussi un thread dans lequel nous nous contentons d'attendre des donnes avant de les transmettre au serveur:
if ((request = reader.readLine()) != null) parent.fireEvent(request, this);
Nous n'irons pas plus avant dans les explications concernant la lecture de donnes puisque c'est exactement la mme mthode que celle utilise pour les sockets clients. Sachez seulement que l'appel fireEvent() est celui qui permettra la classe QuestionSetServer de recevoir les donnes par le biais de la mthode serverEvent().
L'objet client dsigne un objet CaffeineSocket, la mthode getOut() renvoie un flux PrintWriter que nous utilisons exactement comme pour l'envoi de mail en faisant appel println(). La mthode flush() permet de s'assurer que tous les caractres du message ont ts effectivement envoys. L'exemple propos ici, LoginQuiz, tant un petit peu complexe, une tude attentive du code source, comment, vous permettra de saisir toutes les, rares, subtilits et notamment d'approfondir votre exprience des sockets clients.
3.F. Screenshots
4. Les sources
- Le logiciel LoginMail - Le logiciel LoginQuiz
Articles et tutoriels Java L'essentiel de Java en une heure L'API java.nio du JDK 1.4 Inversion de contrle en Java L'introspection Le Java Community Process Conception de tests unitaires avec JUnit Les Strings se dchanent Prsentation de SWT La programmation rseau en Java avec les sockets Du bon usage de l'hritage et de la composition Les rfrences et la gestion de la mmoire en Java Constructeurs et mthodes exportes en Java Les membres statiques, finaux et non immuables en Java Les classes et objets immuables en Java Comprendre et optimiser le Garbage Collector Les principes de la programmation d'une interface graphique Les oprateurs binaires en Java Prenez le contrle du bureau avec JDIC Les Java Data Objects (JDO version 1.0.1) La persistance des donnes avec Hibernate 2.1.8 Journalisation avec l'API Log4j Java 5.0 et les types paramtrs Les annotations de Java 5 Java 1.5 et les types paramtrs Crer un moteur de recherche avec Lucene Articles et tutoriels Swing Threads et performance avec Swing Rechercher avec style en utilisant Swing Splash Screen avec Swing et Java3D Drag & Drop avec style en utilisant Swing Attendre avec style en utilisant Swing Mixer Java3D et Swing Articles et tutoriels Java Web Redcouvrez le web avec Wicket
C ette c ration es t mis e dis pos ition s ous un c ontrat C reative C ommons (P aternit - P artage des C onditions I nitiales l'I dentique).
Responsables bnvoles de la rubrique Java : mlny84 - Mickael Baron - Contacter par email
Developpez.com
Nous contacter Participez Informations lgales
Services
Forum Java Blogs Hbergement
Partenaires
Hbergement Web