Gestion des adresses réseau en Java
COURS programmation réseaux Socket TCP – UDP Master 1 MSRS – FSA Agadir a.boulouz
Références : 1-cours TCP/IP F.Laissus (poly MSIO)
Chaque machine de l'Internet est identifiée par une adresse ou un nom uniques
2-TCP/IP Sockets in Java, L. Cavert , J. Donahoo
Ces deux entités sont gérées sous Java par la classe InetAddress dont voici quelque méthodes
28/11/2010
Master MSRS
1
28/11/2010
Gestion des adresses réseau en Java
Master MSRS
2
Identifier la machine locale
byte [] getAddress() : donne les 4 octets de l'adresse IP de l'instance InetAddress courante String getHostAddress() : donne l'adresse IP de l'instance InetAddress courante String getHostName() : donne le nom Internet de l'instance InetAddress courante InetAddress getByName(String Host) : crée l'instance InetAddress de la machine désignée par Host. Génère une exception si Host est inconnu. Host peut être le nom internet d'une machine ou son adresse IP sous la forme I1.I2.I3.I InetAddress getLocalHost() : crée l'instance InetAddress de la machine sur laquelle s'exécute le programme contenant cette instruction.
28/11/2010
Master MSRS
3
28/11/2010
Master MSRS
4
Identifier la machine locale
Identifier la machine locale
Les résultats de l'exécution sont les suivants : Résultats à l’exécution (si Pc connecté à un réseau (Internet)) Rappel :
IP=41.250.42.36 adresse=41.250.42.36 nom=pcbureauBoulouz identité=pcbureauBoulouz/41.250.42.36
Chaque machine a une adresse IP interne qui est 127.0.0.1. Lorsqu'un programme utilise cette adresse réseau, il utilise la machine sur laquelle il fonctionne. L'intérêt de cette adresse est qu'elle ne nécessite pas de carte réseau. On peut donc tester des programmes réseau sans être connecté à un réseau. Une autre façon de désigner la machine locale est d'utiliser le nom localhost. Voir cours SMI5
si non IP=127.0.0.1 adresse=127.0.0.1 nom=pcbureauBoulouz identité=pcbureauBoulouz/127.0.0.1
28/11/2010
Master MSRS
5
28/11/2010
Identifier une machine quelconque
Master MSRS
6
Identifier une machine quelconque Avec l'appel java getbyname, on obtient les résultats suivants : Sans argument : IP : 127.0.0.1 nom : localhost identité : localhost/127.0.0.1 Exemples de résultat fournit Avec l'appel java getbyname www.menar.ma on obtient : Avec argument : www.menara.ma IP : 41.248.240.28 nom : www.menara.ma identité : www.menara.ma/41.248.240.28 Avec argument : www.msn.com IP : 65.55.17.27 nom : www.msn.com identité : www.msn.com/65.55.17.27
28/11/2010
Master MSRS
7
28/11/2010
Master MSRS
8
Communications TCP-IP
Communications TCP-IP • l'adresse IP ou le nom de la machine B • le numéro du port avec lequel travaille l'application AppB. En effet la machine B peut supporter de nombreuses applications qui travaillent sur l'Internet. Lorsqu'elle reçoit des informations provenant du réseau, elle doit savoir à quelle application sont destinées ces informations. Les applications de la machine B ont accès au réseau via des guichets appelés également des ports de communication. Cette information est contenue dans le paquet reçu par la machine B afin qu'il soit délivré à la bonne application. • les protocoles de communication compris par la machine B. Dans notre étude, nous utiliserons uniquement les protocoles TCP/UDP-IP.
Lorsque une application AppA d'une machine A veut communiquer avec une application AppB d'une machine B de l'Internet, elle doit connaître plusieurs choses :
• le protocole de dialogue accepté par l'application AppB. En effet, les machines A et B vont se "parler". Ce qu'elles vont dire va être encapsulé dans les protocoles TCP-IP. ( pour les caractéristiques de TCP, voir le cours MSRS réseaux partie 2)
28/11/2010
Master MSRS - a.boulouz
9
28/11/2010
La relation client-serveur
Master MSRS
10
Architecture d'un client
Souvent, la communication sur Internet est dissymétrique : la machine A initie une connexion pour demander un service à la machine B : il précise qu'il veut ouvrir une connexion avec le service SB1 de la machine B.
L'architecture d'un programme réseau demandant les services d'une application serveur sera la suivante :
ouvrir la connexion avec le service SB1 de la machine B Celle-ci accepte ou refuse. Si elle accepte, la machine A peut envoyer ses demandes au service SB1. Celles-ci doivent se conformer au protocole de dialogue compris par le service SB1. Un dialogue demande-réponse s'instaure ainsi entre la machine A qu'on appelle machine cliente et la machine B qu'on appelle machine serveur. L'un des deux partenaires fermera la connexion.
28/11/2010
Master MSRS
11
si réussite alors tant que ce n'est pas fini préparer une demande l'émettre vers la machine B attendre et récupérer la réponse la traiter fin tant que finsi
28/11/2010
Master MSRS
12
Architecture d'un serveur
Architecture d'un serveur
L'architecture d'un programme offrant des services sera la suivante : Le programme serveur traite différemment la demande de connexion initiale d'un client de ses demandes ultérieures visant à obtenir un service. Le programme n'assure pas le service lui-même. S'il le faisait, pendant la durée du service il ne serait plus à l'écoute des demandes de connexion et des clients ne seraient alors pas servis. Il procède donc autrement : dès qu'une demande de connexion est reçue sur le port d'écoute puis acceptée, le serveur crée une tâche chargée de rendre le service demandé par le client.
ouvrir le service sur la machine locale tant que le service est ouvert se mettre à l'écoute des demandes de connexion sur un port dit port d'écoute lorsqu'il y a une demande, la faire traiter par une autre tâche sur un autre port dit port de service fin tant que
28/11/2010
Master MSRS
Ce service est rendu sur un autre port de la machine serveur appelé port de service. On peut ainsi servir plusieurs clients en même temps.
13
28/11/2010
Master MSRS
14
Présentation de L’API Socket
Architecture d'un serveur Une tâche de service aura la structure suivante :
tant que le service n'a pas été rendu totalement attendre une demande sur le port de service lorsqu'il y en a une, élaborer la réponse transmettre la réponse via le port de service fin tant que libérer le port de service
28/11/2010
Master MSRS
15
28/11/2010
Master MSRS
16
TCP/IP et les principaux services
28/11/2010
Master MSRS
La notion de « socket »
17
28/11/2010
Processus de Sockets
28/11/2010
Master MSRS
Master MSRS
18
Processus de Sockets
19
28/11/2010
Master MSRS
20
Processus de Sockets - 2
Processus de Sockets - 1
28/11/2010
Master MSRS
21
28/11/2010
Processus de Sockets - 3
28/11/2010
Master MSRS
Master MSRS
22
Processus de Sockets - 4
23
28/11/2010
Master MSRS
24
Processus de Sockets - 5
28/11/2010
Master MSRS
Processus de Sockets - 6
25
28/11/2010
Master MSRS
26
Processus de Sockets – mode non connecté UDP
Processus de Sockets – mode non connecté UDP
Dans l’Internet le protocole UDP (User Datagram Protocol) assure cette fonctionnalité. Le paquetage java.net fourni deux classes pour faciliter la programmation réseau en mode datagramme : DatagramPacket et DatagramSocket. Les données sont mises dans un objet de type DatagramPacket qui est envoyé sur le réseau par le biais d’un objet de type DatagramSocket.
Note :Un datagramme peut être définit comme étant un message qu’on envoie sur le réseau et dont l’arrivée, le temps d’arrivée et le contenu ne sont pas garantis
28/11/2010
Master MSRS
27
28/11/2010
Master MSRS
28
import java.net.*; import java.io.*;
Pour envoyer des datagrammes en Java nous devons suivre les étapes suivantes :
public class CoteEnvoi
• Obtenir l’adresse du destinataire et la mettre dans une instance de la classe InetAddress.
{ static int port=5000;
• Mettre les données et l’adresse dans une instance de la classe DatagramPacket
// Le port UDP de destination
• Créer une instance de la classe DatagramSocket et lui confier l’envoi du datagramme
static InetAddress adr=null; static DatagramSocket sock=null; static String message="Salut!, mode datagramme en illustration";
Pour recevoir des datagrammes en Java nous devons suivre les étapes suivantes :
static byte[] tampon=new byte[message.length()];
• Créer une instance de la classe de la classe DatagramSocket qui devra attendre l’arrivée de données à travers le réseau.
public static void main(String[] args) throws SocketException, IOException { if(args.length!=1) { System.out.println("Donnez comme argumentle nom du destinataire"); System.exit(1); }
• Créer une instance de la classe DatagramPacket qui recevra données qui lui seront passées par l’instance de DatagramSocket.
28/11/2010
Master MSRS
29
try
28/11/2010
Master MSRS
30
La première chose que nous faisons est de résoudre le nom de la machine destinatrice en adresse réseau. Cette adresse sera placée dans un objet de type InetAddress.
{ adr=InetAddress.getByName(args[0]); } catch(UnknownHostException e) { System.out.println("resolution impossible"); System.exit(2); } tampon=message.getBytes(); DatagramPacket paquet=new DatagramPacket(tampon,tampon.length,adr,port); sock=new DatagramSocket();
Ensuite nous transformons notre chaîne de caractères en une suite d’octets afin de les transmettre sur le réseau. N’oublions pas que le réseau ne comprend pas les caractères Unicode (ni toute autre forme d’objet ou de variable). En effet tout ce qu’un réseau comprend est une suite d’octets qui transitent. Cette transformation se fait par la méthode getBytes() de la classe String. Il nous faut ensuite construire un datagramme en indiquant l’emplacement des données à transmettre, leur longueur et enfin l’adresse et le port de destination.
sock.send(paquet); } }
Enfin nous ouvrons une DatagramSocket et utilisons sa méthode send() pour envoyer notre datagramme.
28/11/2010
Master MSRS
31
28/11/2010
Master MSRS
32
Côté réception les choses sont plus faciles. Nous préparons une zone mémoire tampon pour recevoir les données. Ensuite nous créons un DatagramSocket pour écouter sur le port de destination en attente de données. L’ordre d’attente se fait par la méthode receive(). Cette méthode se charge de placer les données dans un DatagramPacket gérant lui même notre tampon. Enfin les données sont extraites du tampon sous forme de chaîne de caractères et imprimées à l’écran.
28/11/2010
Master MSRS
33
import java.net.*; import java.io.*; public class CoteReception { static int port=5000; public static void main(String[] args) throws IOException, SocketException { byte[] tampon=new byte[200]; String message; DatagramSocket sock=new DatagramSocket(port); DatagramPacket paquet=new DatagramPacket(tampon,tampon.length); sock.receive(paquet); message=new String(tampon); System.out.println(message); } }
28/11/2010
Processus de Sockets – mode connecté TCP
Master MSRS
34
Processus de Sockets – mode connecté TCP
Contrairement au mode datagramme, le mode connecté garanti l’arrivée en séquence des données émises en plus de la fiabilité. Dans l’Internet ce mode est assuré au niveau de la couche de transport selon le modèle OSI par le protocole TCP (Transmission Control Protocol). Un tel mode est utile lors d’un transfert de fichiers par exemple.
Le serveur doit : • Instancier la classe ServerSocket et l’instruire à écouter sur un certain port. • Accepter les connexions par la méthode accept() et créer un objet Socket pour faire référence à cette nouvelle connexion. • Faire passer cette nouvelle connexion au programme approprié.
Le paquetage java.net fourni les classes Socket et ServerSocket pour travailler avec le mode connecté.
• Lorsque le traitement est fini fermer la connexion par la méthode close().
Nous allons dans la suite illustrer par un exemple l’utilisation du mode connecté en Java.
Le client doit :
Mais avant d’aborder l’exemple expliquons les étapes que doit effectuer un serveur et un client pour assurer une communication en mode connecté.
• Se connecter au service approprié en instanciant la classe Socket et en lui passant comme paramètres l’adresse du serveur et le port. • Lorsque l’échange est terminé , il ferme la connexion par la méthode close().
28/11/2010
Master MSRS
35
28/11/2010
Master MSRS
36
Le constructeur de la classe ClientConnecte se charge d’ouvrir une connexion vers le serveur dont le nom et le numéro de port sont passés en paramètre. Pour pouvoir envoyer des données sur le réseau nous devons disposer d’un objet de type OutputStream. Cela se fait alors par la fonction getOutputStream() de la classe Socket. Lorsque les données sont envoyées la connexion est fermée par la méthode close(). Il est important de noter qu’il est impératif de traiter les exceptions qui peuvent survenir.
Exemple : voir TPs et exemples (cours)
Du côté du serveur les choses se compliquent un peu plus. Tout d’abord nous devons expliquer la théorie du travail d’un serveur pour pouvoir comprendre notre programme. En général un programme serveur se charge d’écouter sur un port spécifique les demandes de connexion effectuées par les clients. A chaque nouvelle connexion il crée alors un nouveau processus (ou processus léger) qui se charge alors de cette connexion. Le programme principal quant à lui retourne à l’écoute de nouvelles connexions. 28/11/2010
Master MSRS
37
28/11/2010
Master MSRS
38