Introduction aux sockets

Formation

En Ligne

Prix sur demande

Appeler le centre

Avez-vous besoin d'un coach de formation?

Il vous aidera à comparer différents cours et à trouver la solution la plus abordable.

Description

  • Typologie

    Formation

  • Méthodologie

    En ligne

Grâce à cette formation vous pourrez acquérir les connaissances nécessaires qui vous permettrons d’ajouter des compétences à votre profil et obtenir de solides aptitude qui vous offriront de nombreuses opportunités professionnelles.

Questions / Réponses

Ajoutez votre question

Nos conseillers et autres utilisateurs pourront vous répondre

À qui souhaitez-vous addresser votre question?

Saisissez vos coordonnées pour recevoir une réponse

Nous ne publierons que votre nom et votre question

Les Avis

Le programme

Introduction du cours

Bienvenue dans mon tout premier mini-tutoriel consacré aux sockets en langage Java. On ne va pas tout apprendre sur les sockets mais étudier le plus important concernant ces classes du répertoire java.net.

Avant de vous lancer dans la lecture de ce tutoriel, les deux premières parties de cysboy sur le langage Java ainsi que la lecture de celui sur les threads et les flux d'entrées et sorties (1/2) sont primordiales pour bien suivre le cours !

Je vous recommande également de lire le chapitre de Dalshim Bien fermer ses threads en Java si vous voulez bien maîtriser la fermeture de vos threads.

Les sockets servent à communiquer entre deux hôtes appelés Client / Serveur à l'aide d'une adresse IP et d'un port que j'appelle prise ; ces sockets permettront de gérer des flux entrant et sortant afin d'assurer une communication entre les deux (le client et le serveur), soit de manière fiable à l'aide du protocole TCP/IP, soit non fiable mais plus rapide avec le protocole UDP. Nous allons étudier le premier mode, le mode TCP/IP…

Voici ce qu'on peut réaliser à l'aide des sockets :

  • des jeux en ligne ;

  • des systèmes distribués ;

  • des espaces messengers comme MSN Messenger, Yahoo Messenger, … ;

  • des applications comme BitComet permettant de gérer les fichiers .torrent que vous connaissez ;

  • et bien d'autres choses.

Les sockets sont utilisés dans plusieurs autres langages, tels que :

  • le langage C : ( lien vers un tutoriel) ;

  • le langage C++ : (lien vers un autre tutoriel) ;

  • le langage PHP : (lien vers un troisième tutoriel) ;

  • l'Action Script : (aller lire le tutoriel) ;

  • le Erlang : (lien vers le tuto concerné) ;

  • et bien d'autres.

Lire les parties « histoire » et « définitions » de tutoriels ci-dessus ne vous fera pas de mal.
Ne tardons pas et commençons. :)

Récupérer une adresse IP avec InetAddress

Le package java.net de la plate-forme Java fournit une classe InetAddress qui nous permet de récupérer et manipuler son adresse internet, IP pour les intimes. Cette classe n'a pas de constructeur, pour pouvoir avoir une instance de cette classe on a besoin des méthodes de classe. Voici les méthodes dont je vous parle :

  • getLocalHost() : elle retourne un objet qui contient l'adresse IP de la machine locale.

  • getByName(String nom_de_l_machine) : elle retourne un objet qui contient l'adresse IP de la machine dont le nom est passé en paramètre.

  • getAllByName(String nom_de_l_machine) : elle retourne un tableau d'objets qui contient l'ensemble d'adresses IP de la machine qui correspond au nom passé en paramètre.

A présent, voyons les méthodes applicables à un objet de cette classe :

  • getHostName() : elle retourne le nom de la machine dont l'adresse est stockée dans l'objet.

  • getAddress() : elle retourne l'adresse IP stockée dans l'objet sous forme d'un tableau de 4 octets.

  • toString() : elle retourne un String qui correspond au nom de la machine et son adresse.

Et pour terminer un petit exemple :

import java.net.InetAddress; import java.net.UnknownHostException; public class Adressage { public static void main(String[] zero) { InetAddress LocaleAdresse ; InetAddress ServeurAdresse; try { LocaleAdresse = InetAddress.getLocalHost(); System.out.println("L'adresse locale est : "+LocaleAdresse ); ServeurAdresse= InetAddress.getByName("www.siteduzero.com"); System.out.println("L'adresse du serveur du site du zéro est : "+ServeurAdresse); } catch (UnknownHostException e) { e.printStackTrace(); } } }

Et le résultat est :

L'adresse locale est : softdeath/239.254.78.177 L'adresse du serveur du site du zéro est : www.siteduzero.com/80.248.219.123

Fastoche, hein ?

La classe InetAdress peut lever une exception de type UnknownHostException, tâchez de ne pas l'oublier !

Nous savons maintenant comment récupérer l'adresse IP de notre machine ou d'une machine distante, que diriez-vous si l'on l'utilisait pour créer notre tout premier socket ? C'est parti ;)

Qu'est-ce qu'un socket ?

Un socket est un point de terminaison d'une communication bidirectionnelle, c'est-à-dire entre un client et un serveur en cours d'exécution sur un réseau donné. Les deux sont liés par un même numéro de port TCP de sorte que la couche puisse identifier la demande de partage de données.

Un serveur fonctionne sur une machine bien définie et est lié à un numéro de port spécifique. Le serveur se met simplement à l'écoute d'un client, qui demande une connexion.

En outre, java.net comprend la classe ServerSocket, qui met en oeuvre une sorte de prise que les serveurs peuvent utiliser pour écouter et accepter les connexions des clients. Ce qui nous donne :

ServerSocket socketserver = new ServerSocket(numero_port);

Ainsi on obtient un objet de la classe ServerSocket sur un port spécifique : si ce dernier est à 0, le socket est créée sur n'importe quel port libre.

Il existe deux autres constructeurs ; l'un a deux paramètres, le premier est bien sûr le numéro de port et le nombre total de connexion simultanées acceptées, voyez :

ServerSocket socketserver = new ServerSocket(numer_port,nbr_max);

nbr_max est le nombre maximal de connexions traitées simultanément. Par exemple au-delà de cinq tentatives de connexion consécutives autorisées, les connexions sont refusés.

Pour le second constructeur il suffit de spécifier l'adresse locale du serveur.

ServerSocket socketserver = new ServerSocket(numer_port,nbr_max,adresse_locale);

Quant au client, celui-ci connaît le nom de la machine sur laquelle le serveur est en exécution et le numéro de port sur lequel il écoute. Le client va demander une connexion au serveur en s'identifiant avec son adresse IP ainsi que le numéro de port qui lui est lié.

Pour cela, le package java.net fournit une classe Socket qui met en œuvre une connexion bidirectionnelle entre votre programme Java et un autre programme situé sur le réseau. La classe Socket permet de cacher les détails d'implémentation de cette connexion. En utilisant cette classe en lieu et place d'un code natif, vos programmes peuvent communiquer sur le réseau quel que soit la plateforme sur laquelle ils se trouvent. La création d'un socket pour un programme client s'effectue à l'aide d'un des constructeurs suivants :

Socket socket = new Socket(param1, param2)

Le premier paramètre correspond à l'identité du client, il peut être une chaine de caractère ou de type InetAddress, param2 correspond au numéro de port sur lequel on souhaite se connecter sur le serveur. Il est possible également de spécifier son adresse local comme troisième paramètre et le numéro de port local :

Socket socket = new Socket(adresse_distante, port_distant, adresse_locale, port_locale)

Après tentative de connexion, si tout va bien, le serveur accepte la connexion du client, et reçoit un nouveau socket qui est directement lié au même port local. Il a besoin d'une nouvelle prise de sorte qu'elle puisse continuer à écouter le socket d'origine pour les demandes de connexion, tout t'en satisfaisant les besoins du client connecté. Voici comment accepter une connexion d'un client :

Socket socketduserveur = socketserver.accept();

Une fois le socket créé, l'attente de connexion provenant du client se fait à l'aide de la méthode accept().

La méthode accept() reste bloquante tant qu'elle n'a pas détecté de connexion.

Afin d'éviter une attente infinie, il est possible de spécifier un délai maximal d'attente à l'aide d'un mutateur setSoTimeout.

Si un timeout est une valeur strictement positive, l'appel accept() va générer une attente maximale égale à timeout. Si ce temps expire, une exception de type InterruptedIOException est levée sans toute fois que la socket de type ServerSocket ne soit invalidée. La lecture de ce timeout se fait à l'aide de l'accesseur getSoTimeout().

Côté client, si la connexion est acceptée, une socket est créé et le client peut utiliser la socket pour communiquer avec le serveur.
L'établissement d'une connexion peut lever une exception de type IOException.

On va essayer d'établir une communication. Vous avez tout les éléments à portée de main, vous pouvez désormais établir une connexion, au boulot !

...Ce n'était pas si difficile que ça, voyons la correction :)
Le client et le serveur peuvent à présent communiquer par l'écriture ou la lecture de leurs prises. :)

Serveur.java

import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; public class Serveur { public static void main(String[] zero) { ServerSocket socketserver ; Socket socketduserveur ; try { socketserver = new ServerSocket(2009); socketduserveur = socketserver.accept(); System.out.println("Un zéro s'est connecté !"); socketserver.close(); socketduserveur.close(); }catch (IOException e) { e.printStackTrace(); } } }

Client.java

import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; public class Client { public static void main(String[] zero) { Socket socket; try { socket = new Socket(InetAddress.getLocalHost(),2009); socket.close(); }catch (UnknownHostException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } } }

Lancez le serveur en premier et ensuite le client !

Vous venez d'établir votre première connexion entre un serveur et un client . Maintenant, voyons comment envoyer et recevoir des messages.

Attention : il ne faut jamais oublier de fermer le socket ! Sinon si vous utilisez le même port dans un autre programme, ce (l'action de fermer une socket) ne sera plus possible car il (le port) sera occupé !

Échange de message

Une fois la connexion établie et les sockets en possession, il est possible de récupérer le flux d'entrée et de sortie de la connexion TCP vers le serveur. Il existe deux méthodes pour permettre la récupération des flux :

  • getInputStream() de la classe InputStream. Elle nous permet de gérer les flux entrant ;

  • getOutputStream() de la classe OuputStream. Elle nous permet de gérer les flux sortant.

Ces deux méthodes nous permettent donc de gérer les flux en entrée et en sortie. En général le type d'entrée et sortie utilisé est BufferedReader et InputStreamReader pour la lecture, PrintWriter pour l'écriture. Mais on peut utiliser tous les autres flux.

En se basant sur l'annexe du tuto Java :

  • BufferedReader : cette classe permet de lire des caractères à partir d'un flux tamponné, afin de faire des lectures plus rapides ;

  • InputStreamReader : convertit un flux binaire en flux de caractères : elle convertit un objet de type InputStream en objet de type Reader ;

  • PrintWriter : la classe PrintWriter ajoute à un flux la possibilité de faire des écritures sous forme de texte des types primitifs Java, et des chaînes de caractères.

Un petit exemple de communication en image et en code source :

Serveur.java

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; import java.io.PrintWriter; public class Serveur { public static void main(String[] zero) { ServerSocket socketserver ; Socket socketduserveur ; BufferedReader in; PrintWriter out; try { socketserver = new ServerSocket(2009); System.out.println("Le serveur est à l'écoute du port "+socketserver.getLocalPort()); socketduserveur = socketserver.accept(); System.out.println("Un zéro s'est connecté"); out = new PrintWriter(socketduserveur.getOutputStream()); out.println("Vous êtes connecté zéro !"); out.flush(); socketduserveur.close(); socketserver.close(); }catch (IOException e) { e.printStackTrace(); } } }

Client.java

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException; public class Client { public static void main(String[] zero) { Socket socket; BufferedReader in; PrintWriter out; try { socket = new Socket(InetAddress.getLocalHost(),2009); System.out.println("Demande de connexion"); in = new BufferedReader (new InputStreamReader (socket.getInputStream())); String message_distant = in.readLine(); System.out.println(message_distant); socket.close(); }catch (UnknownHostException e) { e.printStackTrace(); }catch (IOException e) { e.printStackTrace(); } } }

Résultat chez le serveur :

Le serveur est à l'écoute du port 2009 Un zéro s'est connecté

Résultat chez le client :

Demande de connexion Vous êtes connecté zéro !

Ho là ! Un instant ! C'est quoi, ces encapsulations et ce flush ?

Rassurez-vous, on va tout expliquer en détail ( ^^ ), surtout ne vous affolez pas.

Côté Serveur

Après établissement de la connexion, le serveur...

Appeler le centre

Avez-vous besoin d'un coach de formation?

Il vous aidera à comparer différents cours et à trouver la solution la plus abordable.

Introduction aux sockets

Prix sur demande