IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

 

Développons en Java   2.30  
Copyright (C) 1999-2022 Jean-Michel DOUDOUX    (date de publication : 15/06/2022)

[ Précédent ] [ Sommaire ] [ Suivant ] [Télécharger ]      [Accueil ]

 

18. L'interaction avec le réseau

 

chapitre    1 8

 

Niveau : niveau 4 Supérieur 

 

Les échanges avec le réseau sont devenus omniprésents dans les applications et entre les applications. Ils permettent notamment :

  • un accès à un serveur comme une base de données
  • d'invoquer des services distants
  • de développer des applications web
  • d'échanger des données entres applications

La plupart de ces fonctionnalités sont mises en oeuvre grâce à des API de haut niveau mais celles-ci utilisent généralement des API de bas niveau pour interagir avec le réseau.

Depuis son origine, Java fournit plusieurs classes et interfaces destinées à faciliter l'utilisation du réseau par programmation en reposant sur les sockets. Celles-ci peuvent être mises en oeuvre pour réaliser des échanges utilisant le protocole réseau IP avec les protocoles de transport TCP ou UDP. Les échanges se font entre deux parties : un client et un serveur.

Ce chapitre contient plusieurs sections :

 

18.1. L'introduction aux concepts liés au réseau

Le modèle OSI (Open System Interconnection) propose un découpage en sept couches des différents composants qui permettent la communication sur un réseau.

Couche Représentation physique ou logicielle
Application Netscape ou Internet Explorer ou une application
Présentation Windows, Mac OS ou Unix
Session WinSock, MacTCP
Transport TCP / UDP
Réseau IP
Liaison PPP, Ethernet
Physique Les câbles et les cartes électroniques

Le protocole IP est un protocole de niveau réseau qui permet d'échanger des paquets d'octets appelés datagrammes. Ce protocole ne garantit pas l'arrivée à bon port des messages. Cette fonctionnalité peut être implémentée par la couche supérieure, comme par exemple avec TCP. Un datagramme IP est l'unité de transfert à ce niveau. Cette série d'octets contient les informations du message, un en-tête (adresses source et de destination, ...) mais aussi des informations de contrôle. Ces informations permettent aux routeurs de faire transiter les paquets sur l'internet.

La couche de transport est implémentée dans les protocoles UDP ou TCP. Elle permet la communication entre des applications sur des machines distantes.

La notion de service permet à une même machine d'assurer plusieurs communications simultanément.

Le système des sockets est le moyen de communication interprocessus développé pour l'Unix Berkeley (BSD). Il est actuellement implémenté sur tous les systèmes d'exploitation utilisant TCP/IP. Une socket est le point de communication par lequel un thread peut émettre ou recevoir des informations et ainsi elle permet la communication entre deux applications à travers le réseau.

La communication se fait sur un port particulier de la machine. Le port est une entité logique qui permet d'associer un service particulier à une connexion. Un port est identifié par un entier de 1 à 65535. Par convention les 1024 premiers sont réservés pour des services standard (80 : HTTP, 21 : FTP, 25: SMTP, ...)

Java prend en charge deux protocoles : TCP et UDP.

Les classes et interfaces utiles au développement réseau sont regroupées dans le package java.net.

 

18.2. Les adresses internet

Une adresse internet permet d'identifier de façon unique une machine sur un réseau. Cette adresse pour le protocole I.P. est sous la forme de quatre octets séparés chacun par un point. Chacun de ces octets appartient à une classe selon l'étendue du réseau.

Pour faciliter la compréhension humaine, un serveur particulier appelé DNS (Domaine Name Service) est capable d'associer un nom à une adresse I.P.

 

18.2.1. La classe InetAddress

Une adresse internet est composée de quatre octets séparés chacun par un point.

Un objet de la classe InetAddress représente une adresse Internet. Cette classe contient des méthodes pour lire une adresse, la comparer avec une autre ou la convertir en chaîne de caractères. Elle ne possède pas de constructeur : il faut utiliser certaines méthodes statiques de la classe pour obtenir une instance de cette classe.

La classe InetAdress encapsule aussi des fonctionnalités pour utiliser les adresses internet.

Méthode Rôle
InetAddress getByName(String) Renvoie l'adresse internet associée au nom d'hôte fourni en paramètre
InetAddress[] getAllByName(String) Renvoie un tableau des adresses internet associées au nom d'hôte fourni en paramètre
InetAddress getLocalHost() Renvoie l'adresse internet de la machine locale
byte[] getAddress() Renvoie un tableau contenant les 4 octets de l'adresse internet
String getHostAddress() Renvoie l'adresse internet sous la forme d'une chaîne de caractères
String getHostName() Renvoie le nom du serveur

Exemple :
import java.net.InetAddress;
import java.net.UnknownHostException;

public class TestNet1 {

  public static void main(String[] args) {
  	try {
      InetAddress adrLocale = InetAddress.getLocalHost(); 
      System.out.println("Adresse locale = "+adrLocale.getHostAddress());
      InetAddress adrServeur = InetAddress.getByName("java.sun.com"); 
      System.out.println("Adresse Sun = "+adrServeur.getHostAddress());
      InetAddress[] adrServeurs = InetAddress.getAllByName("www.microsoft.com");
      System.out.println("Adresses Microsoft : ");
      for (int i = 0; i < adrServeurs.length; i++) {
      	System.out.println("     "+adrServeurs[i].getHostAddress());
      }
    } catch (UnknownHostException e) {
  	  e.printStackTrace();	
  	}
	
  }
}
Résultat :
Adresse locale = 192.166.23.103
Adresse Sun = 192.18.97.71
Adresses Microsoft : 
     207.46.249.27
     207.46.134.155
     207.46.249.190
     207.46.134.222
     207.46.134.190

 

18.3. L'accès aux ressources avec une URL

Une URL (Uniform Resource Locator) ou localisateur de ressource uniforme est une chaîne de caractères qui désigne une ressource précise accessible par Internet ou Intranet. Une URL est donc une référence à un objet dont le format dépend du protocole utilisé pour accéder à la ressource.

Dans le cas du protocole http, l'URL est de la forme :

http://<serveur>:<port>/<chemin>?<param1>&<param2>

Elle se compose du protocole (HTTP), d'une adresse IP ou du nom de domaine du serveur de destination, avec éventuellement un port, un chemin d'accès vers un fichier ou un nom de service et éventuellement des paramètres sous la forme clé=valeur.

Dans le cas du protocole ftp, l'URL est de la forme :

ftp://<user>:<motdepasse>@<serveur>:<port>/<chemin>

Dans le cas d'un e-mail, l'URL est de la forme

mailto:<email>

Dans le cas d'un fichier local, l'URL est de la forme :

file://<serveur>/<chemin>

Elle se compose de la désignation du serveur (non utilisé dans le cas du système de fichiers local) et du chemin absolu de la ressource.

 

18.3.1. La classe URL

Un objet de cette classe encapsule une URL : la validité syntaxique de l'URL est assurée mais l'existence de la ressource représentée par l'URL ne l'est pas.

Exemple d'URL :

http: //www.test.fr :80 /images/image.gif

Dans l'exemple, http représente le protocole, www.test.fr représente le serveur, 80 représente le port, /images/image.gif représente la ressource.

Le nom du protocole indique au navigateur le protocole qui doit être utilisé pour accéder à la ressource. Il existe plusieurs protocoles sur internet : http, ftp, smtp ...

L'identification du serveur est l'information qui désigne une machine sur le réseau, identifiée par une adresse IP. Cette adresse s'écrit sous la forme de quatre entiers séparés par un point. Une machine peut se voir affecter un nom logique (hostname) composé d'un nom de machine (ex : www), d'un nom de sous domaine (ex : toto) et d'un nom de domaine (ex :fr). Chaque domaine possède un serveur de nom (DNS : Domain Name Server) chargé d'effectuer la correspondance entre les noms logiques et les adresses IP.

Le numéro de port désigne le service. En mode client/serveur, un client s'adresse à un programme particulier (le service) qui s'exécute sur le serveur. Le numéro de port identifie ce service. Cette information est facultative dans l'URL : par exemple si aucun numéro n'est précisé dans une url, un browser dirige sa demande vers un port standard : par défaut, le service http est associé au port 80, le service ftp au port 21, etc ...

L'identification de la ressource indique le chemin d'accès de celle-ci sur le serveur.

Le constructeur de la classe lève une exception du type MalformedURLException si la syntaxe de l'URL n'est pas correcte.

Les objets créés sont constants et ne peuvent plus être modifiés par la suite.

Exemple :
  URL pageURL = null;
  try { 
    pageURL = new URL(getDocumentBase( ), "http://www.javasoft.com"); 
  } catch (MalformedURLException mue) {}

La classe URL possède des getters pour obtenir les différents éléments qui la composent : getProtocole(), getHost(), getPort(), getFile().

La méthode openStream() ouvre un flux de données en entrée pour lire la ressource et renvoie un objet de type InputStream.

La méthode openConnection() ouvre une connexion vers la ressource et renvoie un objet de type URLConnexion

 

18.3.2. La classe URLConnection

Cette classe abstraite encapsule une connexion vers une ressource désignée par une URL pour obtenir un flux de données ou des informations sur la ressource.

Exemple :
import java.net.*;
import java.io.*;

public class TestURLConnection {

	public static void main(String[] args) {

		String donnees;

		try {

			URL monURL = new URL("http://localhost/fichiers/test.txt");
			
			URLConnection connexion = monURL.openConnection();
			InputStream flux = connexion.getInputStream();

			int donneesALire = connexion.getContentLength();

			for(;donneesALire != 0; donneesALire--)
 			System.out.print((char)flux.read());

			// Fermeture de la connexion

			flux.close();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Pour cet exemple, le fichier test.txt doit être accessible via le serveur web dans le répertoire "fichiers".

 

18.3.3. La classe URLEncoder

Cette classe est une classe utilitaire qui propose la méthode statique encode() pour encoder une URL. Elle remplace notamment les espaces par un signe "+" et les caractères spéciaux par un signe "%" suivi du code du caractère.

Exemple :
import java.net.*;

public class TestEncodeURL {

  public static void main(String[] args) {
  	String url = "http://www.test.fr/images perso/mon image.gif";
  	System.out.println(URLEncoder.encode(url));
  }
}
Résultat :
http%3A%2F%2Fwww.test.fr%2Fimages+perso%2Fmon+image.gif

Depuis le JDK 1.4, il existe une version surchargée de la méthode encode() qui nécessite le passage d'un paramètre supplémentaire : une chaîne de caractères qui précise le format d'encodage des caractères. Cette méthode remplace l'ancienne méthode encode() qui est dépréciée. Elle peut lever une exception du type UnsupportedEncodingException.

Exemple (JDK 1.4) :
import java.io.UnsupportedEncodingException;
import java.net.*;

public class TestEncodeURL {

  public static void main(String[] args) {
  	try {
  	  String url = "http://www.test.fr/images perso/mon image.gif";
  	  System.out.println(URLEncoder.encode(url,"UTF-8"));
  	  System.out.println(URLEncoder.encode(url,"UTF-16"));
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
  	}
  }
}
Exemple :
http%3A%2F%2Fwww.test.fr%2Fimages+perso%2Fmon+image.gif
http%FE%FF%00%3A%00%2F%00%2Fwww.test.fr%FE%FF%00%2Fimages+perso%FE%FF%00%2Fmon+image.gif

 

18.3.4. La classe HttpURLConnection

Cette classe qui hérite de URLConnection encapsule une connexion utilisant le protocole HTTP.

Exemple :
import java.net.*;
import java.io.*;

public class TestHttpURLConnection {

  public static void main(String[] args) {
    HttpURLConnection connexion = null;
    
   try {
    URL url = new URL("http://java.sun.com");

    System.out.println("Connexion a l'url ...");
    connexion = (HttpURLConnection) url.openConnection();

    connexion.setAllowUserInteraction(true);
    DataInputStream in = new DataInputStream(connexion.getInputStream());
 
      if (connexion.getResponseCode() != HttpURLConnection.HTTP_OK) {
        System.out.println(connexion.getResponseMessage());
      } else {
        while (true) {
          System.out.print((char) in.readUnsignedByte());
        }
      }
    } catch (Exception e) {
    	e.printStackTrace();
    } finally {
      connexion.disconnect();
      }
    System.exit(0);
  }
}

 

18.4. L'utilisation du protocole TCP

TCP est un protocole qui permet une connexion de type point à point entre deux applications. C'est un protocole fiable qui garantit la réception dans l'ordre d'envoi des données. En contre-partie, ce protocole offre de moins bonnes performances mais c'est le prix à payer pour la fiabilité.

TCP utilise la notion de port pour permettre à plusieurs applications d'exploiter ce même protocole.

Dans une liaison entre deux ordinateurs, l'un des deux joue le rôle de serveur et l'autre celui de client.

 

18.4.1. La classe ServerSocket

La classe ServerSocket est utilisée côté serveur : elle attend simplement les appels du ou des clients. C'est un objet du type Socket qui prend en charge la transmission des données.

Cette classe représente la partie serveur du socket. Un objet de cette classe est associé à un port sur lequel il va attendre les connexions d'un client. Généralement, à l'arrivée d'une demande de connexion, un thread est lancé pour assurer le dialogue avec le client sans bloquer les connexions des autres clients.

La classe ServerSocket possède plusieurs constructeurs dont les principaux sont :

Constructeur Rôle
ServerSocket() Constructeur par défaut
ServerSocket(int) Créer une socket sur le port fourni en paramètre
ServerSocket(int, int) Créer une socket sur le port et avec la taille maximale de la file fournis en paramètres

Tous ces constructeurs peuvent lever une exception de type IOException.

La classe ServerSocket possède plusieurs méthodes :

Méthode Rôle
Socket accept() Attendre une nouvelle connexion
void close() Fermer la socket

Si un client tente de communiquer avec le serveur, la méthode accept() renvoie une socket qui encapsule la communication avec ce client.

Le mise en oeuvre de la classe ServerSocket suit toujours la même logique :

  • créer une instance de la classe ServerSocket en précisant le port en paramètre
  • définir une boucle sans fin contenant les actions ci-dessous
  • appelle de la méthode accept() qui renvoie une socket lors d'une nouvelle connexion
  • obtenir un flux en entrée et en sortie à partir de la socket
  • écrire les traitements à réaliser
Exemple ( code Java 1.2 ) :
import java.net.*;
import java.io.*;

public class TestServeurTCP {
  final static int port = 9632;

  public static void main(String[] args) {
    try {
      ServerSocket socketServeur = new ServerSocket(port);
      System.out.println("Lancement du serveur");

      while (true) {
        Socket socketClient = socketServeur.accept();
        String message = "";

        System.out.println("Connexion avec : "+socketClient.getInetAddress());

        // InputStream in = socketClient.getInputStream();

        // OutputStream out = socketClient.getOutputStream();


        BufferedReader in = new BufferedReader(
          new InputStreamReader(socketClient.getInputStream()));
        PrintStream out = new PrintStream(socketClient.getOutputStream());
        message = in.readLine();
        out.println(message);

        socketClient.close();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

L'inconvénient de ce modèle est qu'il ne peut traiter qu'une connexion à la fois. Pour pouvoir traiter plusieurs connexions simultanément, il faut créer un nouveau thread contenant les traitements à réaliser sur la socket.

Exemple :
import java.net.*;
import java.io.*;

public class TestServeurThreadTCP extends Thread {

  final static int port = 9632;
  private Socket socket;

  public static void main(String[] args) {
    try {
      ServerSocket socketServeur = new ServerSocket(port);
      System.out.println("Lancement du serveur");
      while (true) {
        Socket socketClient = socketServeur.accept();
        TestServeurThreadTCP t = new TestServeurThreadTCP(socketClient);
        t.start();
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public TestServeurThreadTCP(Socket socket) {
    this.socket = socket;
  }

  public void run() {
    traitements();
  }

  public void traitements() {
    try {
      String message = "";

      System.out.println("Connexion avec le client : " + socket.getInetAddress());

      BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      PrintStream out = new PrintStream(socket.getOutputStream());
      message = in.readLine();
      out.println("Bonjour " + message);

      socket.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

 

18.4.2. La classe Socket

Les sockets implémentent le protocole TCP (Transmission Control Protocol). La classe contient les méthodes de création des flux d'entrée et de sortie correspondants. Les sockets constituent la base des communications par le réseau.

Comme les flux Java sont transformés en format TCP/IP, il est possible de communiquer avec l'ensemble des ordinateurs qui utilisent ce même protocole. La seule condition importante au niveau du système d'exploitation est qu'il soit capable de gérer ce protocole.

Cette classe encapsule la connexion à une machine distante par le réseau. Elle gère la connexion, l'envoi de données, la réception de données et la déconnexion.

La classe Socket possède plusieurs constructeurs dont les principaux sont :

Constructeur Rôle
Socket() Constructeur par défaut
Socket(String, int) Créer une socket sur la machine dont le nom et le port sont fournis en paramètres
Socket(InetAddress, int) Créer une socket sur la machine dont l'adresse IP et le port sont fournis en paramètres

La classe Socket possède de nombreuses méthodes dont les principales sont :

Méthode Rôle
InetAddress getInetAddress() Renvoie l'adresse I.P. à laquelle la socket est connectée
void close() Fermer la socket
InputStream getInputStream() Renvoie un flux en entrée pour recevoir les données de la socket
OutputStream getOutputStream() Renvoie un flux en sortie pour émettre les données de la socket
int getPort() Renvoie le port utilisé par la socket

Le mise en oeuvre de la classe Socket suit toujours la même logique :

  • créer une instance de la classe Socket en précisant la machine et le port en paramètres
  • obtenir un flux en entrée et en sortie
  • écrire les traitements à réaliser
Exemple :
import java.net.*;
import java.io.*;

public class TestClientTCP {
  final static int port = 9632;

  public static void main(String[] args) {

    Socket socket;
    DataInputStream userInput;
    PrintStream theOutputStream;

    try {
      InetAddress serveur = InetAddress.getByName(args[0]);
      socket = new Socket(serveur, port);

      BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      PrintStream out = new PrintStream(socket.getOutputStream());

      out.println(args[1]);
      System.out.println(in.readLine());

    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

 

18.5. L'utilisation du protocole UDP

UDP est un protocole basé sur IP qui permet une connexion de type point à point ou de type multipoint. C'est un protocole qui ne garantit pas que les données arriveront dans l'ordre d'émission. En contre-partie, ce protocole offre de bonnes performances car il est très rapide mais à réserver à des tâches peu importantes.

Pour assurer les échanges, UDP utilise la notion de port, ce qui permet à plusieurs applications d'utiliser UDP sans que les échanges interfèrent les uns avec les autres. Cette notion est similaire à la notion de port utilisée par TCP.

UDP est utilisé dans de nombreux services "standard" tels que echo (port 7), DayTime (13), etc ...

L'échange de données avec UDP se fait avec deux sockets, l'une sur le serveur, l'autre sur le client. Chaque socket est caractérisée par une adresse internet et un port.

Pour utiliser le protocole UDP, Java définit deux classes DatagramSocket et DatagramPacket.

 

18.5.1. La classe DatagramSocket

Cette classe crée un Socket qui utilise le protocole UDP (Unreliable Datagram Protocol) pour émettre ou recevoir des données.

Cette classe possède plusieurs constructeurs :

Constructeur Rôle
DatagramSocket() Créer une socket attachée à toutes les adresses IP de la machine et à un des ports libres sur la machine
DatagramSocket(int) Créer une socket attachée à toutes les adresses IP de la machine et au port précisé en paramètre
DatagramSocket(int, InetAddress) Créer une socket attachée à l'adresse IP et au port précisés en paramètres

Tous les constructeurs peuvent lever une exception de type SocketException : en particulier, si le port précisé est déjà utilisé lors de l'instanciation de l'objet DatagramSocket, une exception de type BindException est levée. Cette exception hérite de SocketException.

La classe DatagramSocket définit plusieurs méthodes :

Méthode Rôle
close() Fermer la socket et ainsi libérer le port
receive(DatagramPacket) Recevoir des données
send(DatagramPacket) Envoyer des données
int getPort() Renvoyer le port associé à la socket
void setSoTimeout(int) Préciser un timeout d'attente pour la réception d'un message.

Par défaut, un objet DatagramSocket ne possède pas de timeout lors de l'utilisation de la méthode receive(). La méthode bloque donc l'exécution de l'application jusqu'à la réception d'un packet de données. La méthode setSoTimeout() permet de préciser un timeout en millisecondes. Une fois ce délai écoulé sans réception d'un paquet de données, la méthode lève une exception du type SocketTimeoutException.

 

18.5.2. La classe DatagramPacket

Cette classe encapsule une adresse internet, un port et les données qui sont échangées grâce à un objet de type DatagramSocket. Elle possède plusieurs constructeurs pour encapsuler des paquets émis ou reçus.

Constructeur Rôle
DatagramPacket(byte tampon[], int taille) Encapsule des paquets en réception dans un tampon
DatagramPacket(byte port[], int taille, InetAddress adresse, int port) Encapsule des paquets en émission à destination d'une machine

Cette classe propose plusieurs méthodes pour obtenir ou mettre à jour les informations sur le paquet encapsulé.

Méthode Rôle
InetAddress getAddress () Renvoyer l'adresse du serveur
byte[] getData() Renvoyer les données contenues dans le paquet
int getPort () Renvoyer le port
int getLength () Renvoyer la taille des données contenues dans le paquet
setData(byte[]) Mettre à jour les données contenues dans le paquet

Le format des données échangées est un tableau d'octets, il faut donc correctement initialiser la propriété length qui représente la taille du tableau pour un paquet émis et utiliser cette propriété pour lire les données dans un paquet reçu.

 

18.5.3. Un exemple de serveur et de client

L'exemple suivant est très simple : un serveur attend un nom d'utilisateur envoyé sur le port 9632. Dès qu'un message lui est envoyé, il renvoie à son expéditeur "bonjour" suivi du nom reçu du client, de son IP et du numéro du port.

Exemple : le serveur
import java.io.*;
import java.net.*;

public class TestServeurUDP {

  final static int port = 9632;
  final static int taille = 1024;
  static byte buffer[] = new byte[taille];

  public static void main(String argv[]) throws Exception {
    DatagramSocket socket = new DatagramSocket(port);
    String donnees = "";
    String message = "";
    int taille = 0;

    System.out.println("Lancement du serveur");
    while (true) {
      DatagramPacket paquet = new DatagramPacket(buffer, buffer.length);
      DatagramPacket envoi = null;
      socket.receive(paquet);

      System.out.println("\n"+paquet.getAddress());
      taille = paquet.getLength();
      donnees = new String(paquet.getData(),0, taille);
      System.out.println("Donnees reçues = "+donnees);

      message = "Bonjour "+donnees;
      System.out.println("Donnees envoyees = "+message);
      envoi = new DatagramPacket(message.getBytes(), 
        message.length(), paquet.getAddress(), paquet.getPort());
      socket.send(envoi);
    }
  }
}
Exemple : le client
import java.io.*;
import java.net.*;

public class TestClientUDP {

  final static int port = 9632;
  final static int taille = 1024;
  static byte buffer[] = new byte[taille];

  public static void main(String argv[]) throws Exception {
    try {
      InetAddress serveur = InetAddress.getByName(argv[0]);
      int length = argv[1].length();
      byte buffer[] = argv[1].getBytes();
      DatagramSocket socket = new DatagramSocket();
      DatagramPacket donneesEmises = new DatagramPacket(buffer, length, serveur, port);
      DatagramPacket donneesRecues = new DatagramPacket(new byte[taille], taille);

      socket.setSoTimeout(30000);
      socket.send(donneesEmises);
      socket.receive(donneesRecues);

      System.out.println("Message : " + new String(donneesRecues.getData(), 
        0, donneesRecues.getLength()));
      System.out.println("de : " + donneesRecues.getAddress() + ":" + 
        donneesRecues.getPort());
    } catch (SocketTimeoutException ste) {
      System.out.println("Le delai pour la reponse a expire");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

L'utilisation du client nécessite de fournir en paramètres l'adresse internet du serveur et le nom de l'utilisateur.

Exécution du client :
C:\>java TestClientUDP www.test.fr "Michel"
java.net.UnknownHostException: www.test.fr: www.test.fr
        at java.net.InetAddress.getAllByName0(InetAddress.java:948)
        at java.net.InetAddress.getAllByName0(InetAddress.java:918)
        at java.net.InetAddress.getAllByName(InetAddress.java:912)
        at java.net.InetAddress.getByName(InetAddress.java:832)
        at TestClientUDP.main(TestClientUDP.java:12)

C:\>java TestClientUDP 192.168.25.101 "Michel"
Le delai pour la reponse a expire

C:\>java TestClientUDP 192.168.25.101 "Michel"
Message : Bonjour Michel
de : /192.168.25.101:9632

 

18.6. Les exceptions liées au réseau

Le package java.net définit plusieurs exceptions :

Exception Rôle / Définition
BindException Connection au port local impossible : le port est peut être déjà utilisé
ConnectException Connection à une socket impossible : aucun serveur n'écoute sur le port précisé
MalformedURLException L'URL n'est pas valide
NoRouteToHostException Connection à l'hôte impossible : un firewall empêche la connexion
ProtocolException Une erreur est survenue au niveau du protocle sous-jacent (TCP par exemple)
SocketException Une erreur est survenue au niveau du protocle sous-jacent
SocketTimeoutException Délai d'attente pour la réception ou l'émission des données écoulé
UnknownHostException L'adresse IP de l'hôte n'a pas pu être trouvée
UnknownServiceException

Une erreur est survenue au niveau de la couche service : par exemple, le type MIME retourné est incorrect ou l'application tente d'écrire sur une connexion en lecture seule

URISyntaxException La syntaxe de l'URI utilisée est invalide

 

18.7. Les interfaces de connexions au réseau

Le J2SE 1.4 ajoute une nouvelle classe qui encapsule les interfaces de connexions aux réseaux et qui permet d'obtenir la liste des interfaces de connexions de la machine. Cette classe est la classe NetworkInterface.

Une interface de connexions au réseau se caractérise par un nom court, une désignation et une liste d'adresses IP. La classe possède des getters sur chacun de ses éléments :

Méthode Rôle
String getName() Renvoie le nom court de l'interface
String getDisplayName() Renvoie la désignation de l'interface
Enumeration getInetAddresses() Renvoie une énumération d'objets InetAddress contenant la liste des adresses IP associées à l'interface

Cette classe possède une méthode statique getNetwotkInterfaces() qui renvoie une énumération contenant des objets de type NetworkInterface encapsulant les différentes interfaces présentes dans la machine.

Exemple :
import java.net.*;
import java.util.*;

public class TestNetworkInterface {

  public static void main(String[] args) {
    try {
      TestNetworkInterface.getLocalNetworkInterface();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  private static void getLocalNetworkInterface() throws SocketException, 
    NoClassDefFoundError {
    Enumeration interfaces = NetworkInterface.getNetworkInterfaces();

    while (interfaces.hasMoreElements()) {
      NetworkInterface ni;
      Enumeration adresses;

      ni = (NetworkInterface) interfaces.nextElement();

      System.out.println("Network interface : ");
      System.out.println("  nom court    = " + ni.getName());
      System.out.println("  désignation  = " + ni.getDisplayName());

      adresses = ni.getInetAddresses();
      while (adresses.hasMoreElements()) {
        InetAddress ia = (InetAddress) adresses.nextElement();
        System.out.println("  adresse I.P. = " + ia);
      }
    }
  }

}
Résultat :
Network interface : 
  nom court    = MS TCP Loopback interface
  désignation  = lo
  adresse I.P. = /127.0.0.1
Network interface : 
  nom court    = Carte Realtek Ethernet à base RTL8029(AS)(Générique)
  désignation  = eth0
  adresse I.P. = /169.254.166.156
Network interface : 
  nom court    = WAN (PPP/SLIP) Interface
  désignation  = ppp0
  adresse I.P. = /193.251.70.245<

 

 


[ Précédent ] [ Sommaire ] [ Suivant ] [Télécharger ]      [Accueil ]

78 commentaires Donner une note à l´article (5)

 

Copyright (C) 1999-2022 Jean-Michel DOUDOUX. Vous pouvez copier, redistribuer et/ou modifier ce document selon les termes de la Licence de Documentation Libre GNU, Version 1.1 ou toute autre version ultérieure publiée par la Free Software Foundation; les Sections Invariantes étant constitués du chapitre Préambule, aucun Texte de Première de Couverture, et aucun Texte de Quatrième de Couverture. Une copie de la licence est incluse dans la section GNU FreeDocumentation Licence. La version la plus récente de cette licence est disponible à l'adresse : GNU Free Documentation Licence.