ABCSITE

INFORMATIQUE

 
 
 

 
 

 Java 

le package java.net

 

Nous allons étudier dans ce chapitre les mécanisme à mettre en place pour pouvoir ouvrir une connexion réseau entre deux applications. Cette connexion sera établie par des sockets. Il en résulte plusieurs protocoles utilisables. Seuls deux sont implémentés en Java : le protocole TCP/IP et le protocole UDP.

Quelques définitions.

Le protocole UDP permet d'établir une connexion, sur une socket, en mode non connecté. Pour simplifier les choses, on peut dire qu'un programme va envoyer un paquet d'information (ou plusieurs) sur le réseau et qu'il n'a aucune garanti que ce paquet arrive à destination. Pire encore, s'il envoie plus d'un paquet, l'ordre de réception n'est pas garantit. Il est donc clair qu'il est à la charge du programmeur de l'application, de mettre en place un mécanisme assurant une connexion fiable.

Le protocole TCP/IP est lui, plus sympathique dans le sens ou il permet d'établir une connexion en mode connecté. Une donnée envoyée est donc sûr d'arriver à bon port. Mieux si plusieurs données sont envoyées consécutivement, elles seront traitées, de l'autre coté de la connexion, de le même ordre.

Il est donc clair que le protocole TCP/IP est plus simple à utiliser. Cependant, il assurera une connexion moins performante en terme de temps d'exécution. Il faut savoir que ce protocole est une sur-couche du protocole UDP.

Afin de mettre en place une connexion, différentes classes vous sont proposées en fonctions du protocole choisi.

Ouverture d'une connexion en mode TCP/IP.

Plusieurs choses sont à spécifier pour pouvoir correctement ouvrir une telle connexion. Tout d'abord, nous allons devoir utiliser les classes Socket et SocketServer. Ensuite, il va nous falloir utiliser des flots de caractères pour pouvoir envoyer et récupérer des données sur la socket. Il ne faut pas perdre de vue qu'une socket est bi-directionnelle : on peut à la fois y lire et y écrire. Il va aussi vous falloir déterminer un protocole d'échange de données entre vos clients et votre serveur. Une fois ces considérations étudiées, il ne vous reste plus qu'à coder votre solution.

Considérons tout d'abord, le coté serveur. La première chose à faire, est d'enregistrer son service sous un numéro de port (avec un nombre de connexions maximum à la socket de service). Ensuite, on place cette socket d'écoute en attente d'une nouvelle connexion : cela se réalise en appelant la méthode accept sur un objet instancié sur la classe ServerSocket. Si un client se connecte au service, la méthode accept vous rend alors un objet de type Socket. Il ne vous reste plus récupérer les flots associés à cette socket pour établir la connexion. L'échange des données peut commencer.

Au niveau du client, c'est aussi simple. On créer une socket sur la machine dite serveur, au numéro de port convenu. Une fois la connexion établie, il ne reste plus qu'à dialoguer de manière analogue.

L'exemple suivant vous donne un petit aperçu de la manière dont doit être écrit un serveur, ainsi qu'un client. La problématique liée à l'échange de données n'est pas traitée dans l'exemple.

server.java 

try {
ServerSocket ecoute = new ServerSocket(5432,5);
Socket service = (Socket)null;
while(true) {
service = ecoute.accept();
OutputStream os = service.getOutputStream();
InputStream is = service.getInputStream();
os.write(is.read());
service.close();
}
} catch (Exception e) {
// traitement d'erreur
}

 

client.java 

try {
Socket s = new Socket("serverName",5432);
OutputStream os = s.getOutputStream();
InputStream is = s.getInputStream();
os.write((int)'a'); // OutputStream et non pas Writer
System.out.println(is.read());
s.close();
} catch(Exception e) {
// Traitement d'erreur
}



J'espère que vous serez d'accord avec moi pour dire que ce n'est pas vraiment très difficile d'ouvrir une connexion avec le protocole TCP/IP. Peut-être trouverez vous que cela est plus complexe avec le protocole UDP.

Ouverture d'une connexion en mode UDP.

En effet, maintenant ca se complique un peu. On n'utilisera plus les flots de données pour faire transiter ces dernières, mais des paquets. Rappelons de suite que vous n'avez aucune certitude quant à l'ordre d'arrivée des paquets, et pire encore vous n'êtes pas certain de tous les recevoir.

Commençons donc par voir comment nous devons procéder pour générer un paquet. En premier lieu, on utilise la classe DatagramPacket. Un paquet devra de plus être initialisé différemment selon qu'il est pour vocation de recevoir ou d'être transmit. Autre petit détail important, vous ne gérez pas de connexion comme cela pouvait être le cas précédemment : les informations relatives à la connexion font partie intégrante du paquet

L'exemple suivant montre donc un exemple de communication en mode UDP. Un programme envoie un paquet, l'autre tente de le recevoir.


envoyeur.java

InetAddress address = InetAddress.getByName("hostName");
int port = 4321;
String ch = "Le message à envoyer";
int chl = ch.length;
byte[] message = new byte[chl];
ch . getBytes(0,chl,message,0);
DatagramPacket p = new DatagramPacket(message, chl, address, port);
datagramSocket s = new DatagramSocket();
s.send(p);

 

receveur.java

byte[] buffer = new byte[1024];
String ch;
DatagramPacket p = new DatagramPacket(buffer, buffer.length);
datagramSocket s = new DatagramSocket(4321);
while(true) {
s.receive(p);
ch = new String(buffer,0,0,p.getLength());
System.out.println("Paquet recu : message = " + ch +
" - envoyeur = " +
p.getAddress.getHostName() +
" - port = " + p.getPort());
}


Si maintenant, le receveur doit renvoyer un message, il doit lui aussi faire la même chose que l'envoyeur. La mise en place d'un tel mécanisme est donc lourde, d'autant plus qu'il est à votre charge de stoker dans les paquets des informations utiles quant au numéro du paquet parmi d'autres, voir de le renvoyer si un réponse n'est pas reçue rapidement. Je vous laisse méditer sur le problème.


 
 

ABCSITE © copyright 2002