Reseaujava
Reseaujava
Reseaujava
en Java
Didier Donsez
Université de Valenciennes
Institut des Sciences et Techniques de Valenciennes
donsez@univ-valenciennes.fr
L ’API Réseau de Java
java.net
• Classes et interfaces du paquetage java.net
n Adresses IP
InetAddress
n Socket TCP
Socket, ServerSocket
Programmation Réseau en Java, D. Donsez, 1999-2000
n Sockets UDP
DatagramSocket, DatagramPacket
n Sockets MultiCast
MulticastSocket, DatagramPacket
n Classes réseau niveau application (couche 7)
URL, URLConnection, HttpURLConnection, JarURLConnection
,2
La classe java.net.InetAddress
• Exemple
InetAddress server;
try {
if (args.length > 0) { server = InetAddress.getByName(args[0]); }
else { server = InetAddress.getLocalHost(); }
System.out.println(server); // affiche le nom du server
} catch (UnknownHostException e) { System.out.println("Could not find this computer's address."); }
,3
Exemple d ’après [Rusty - chapitre 4]
avec java.net.InetAddress
package java.net; import java.util.StringTokenizer;
public class InetAddressFactory { // d ’après [Rusty - chapitre 4]
// Use a byte array like {199, 1, 32, 90} to build an InetAddressObject
public static InetAddress newInetAddress(byte addr[]) throws UnknownHostException {
try { InetAddress ia = new InetAddress();
ia.address = (addr[3] & 0xFF) | ((addr[2] << 8) & 0xFF00);
| ((addr[1] << 16) & 0xFF0000) | ((addr[0] << 24) & 0xFF000000);
return ia;
Programmation Réseau en Java, D. Donsez, 1999-2000
,6
Socket TCP
Déroulement de l ’exécution
hostcli hostser
hostcli hostser
JVM
JVMTCPClient
TCPClient JVM
JVMTCPServer
TCPServer
main thread main thread
person thread(s) Création d ’un ServerSocket
Attente d ’une demande de connexion
accept()
Récupération
Récupération des flots d ’entrée et de sortie
des flots d ’entrée et de sortie getInputStream() et getOutputStream()
Programmation Réseau en Java, D. Donsez, 1999-2000
getInputStream() et getOutputStream()
,7
Socket TCP
Remarques lors du déroulement de l ’exécution
n Le serveur
• Après la fermeture de la connexion, le serveur se met en attente du nouvelle
connexion du même client ou d ’un autre
• Si plusieurs demandes connexions arrivent simultanément, une seule est acceptée
et les autres sont mises en attente jusqu ’au accept() suivant (modulo les timeouts)
• pour accepter et traiter plusieurs connexions simultanées, la solution est de multithreadé
le serveur
Programmation Réseau en Java, D. Donsez, 1999-2000
n Le protocole
• Le client et le serveur doivent respecter un protocole valide d ’échange des
données selon un automate.
• le client envoie un entier mais le serveur attend un flottant
• le client attend des données du serveur qui lui même attend des données du client
il y a interblocage
• Attention à l ’hétérogénéité des plates-formes client et serveur
• un client sur Intel envoie un entier little-endian
• le serveur sur Sparc reçoit cet entier et le traite en big-endian
,8
Socket TCP Remarques lors du
déroulement de l ’exécution
n Echange en mode Ligne
• Les requêtes et les réponses sont constituées
d ’une ou plusieurs lignes de texte (ASCII 7 bits, www-url-encoded, ...)
Classes java.io.BufferedReader/BufferedWriter
• Exemple de protocole en mode ligne : HTTP, FTP, SMTP, …
• Avantage pour le deboggage : le client peut être un client telnet
telnet www 80, telnet mailhost 25
Programmation Réseau en Java, D. Donsez, 1999-2000
socket.close();
} catch(IOException ioe) {
System.out.println("Erreur de connection : " + ioe.getMessage());
}
}…
n Remarque :
• l ’API JavaMail est préférable pour l ’envoi des courriers ! , 13
Exemple d ’un Code d ’un Client SMTP
(ii)
static void SMTP(
BufferedReader br, DataOutputStream out,
String MAILDOMAIN, String FROM, String TO, String SUBJECT, String MSG){
String cmdstr, statusline;
statusline = br.readLine(); System.out.print(statusline); // le serveur se présente
cmdstr="HELO " + MAILDOMAIN + CRLF; // EHLO pour les ordres étendus
out.writeBytes(cmdstr); out.flush(); System.out.print(cmdstr);
statusline = br.readLine(); System.out.println(statusline);
cmdstr ="MAIL FROM:"+ FROM + CRLF;
out.writeBytes(cmdstr); out.flush(); System.out.print(cmdstr);
Programmation Réseau en Java, D. Donsez, 1999-2000
n java.net.BindException
• erreur de liaison à une adresse locale (le port est peut être déjà
lié)
n java.net.ConnectException
• refus de connexion par l ’hôte (pas de process qui écoute le
port, … )
Programmation Réseau en Java, D. Donsez, 1999-2000
n java.net.NoRouteToHostException
• le hôte n ’est pas joignable
n java.net.ProtocolException
• erreur du protocole (TCP, … )
n java.net.SocketException
• erreur du protocole (TCP, … )
n java.net.UnknownHostException
• erreur de DNS
, 16
Serveur Multithreadé
n Motivation
• Accepter (et servir) plusieurs connexions simultanées
de plusieurs clients
n Méthode
• une thread (dite dispatcher) attend les demandes de
connexions
Programmation Réseau en Java, D. Donsez, 1999-2000
, 18
Code du Serveur Multithreadé
import java.net.*; import java.io.*;
public class EchoServer extends Thread {
private Socket clientSocket;
EchoServer(Socket clientSocket) {this.clientSocket=clientSocket;}
public static void main(String[] args) {
ServerSocket listenSocket;
try {
listenSocket = new ServerSocket(Integer.parseInt(args[0])); // port
while(true) { // le dispatcher est la thread qui exécute main()
Programmation Réseau en Java, D. Donsez, 1999-2000
n Motivation
• il est souvent nécessaire de traiter les données à envoyer ou reçues d ’un
java.net.Socket (compression, conversion, filtrage, chiffrage, … )
• Post-traitement des données après réception (ex: Décompression, Déchiffrage)
• Pré-traitement des données avant envoi (ex: Compression, Chiffrage)
n 2 Méthodes
Programmation Réseau en Java, D. Donsez, 1999-2000
, 20
Personnaliser un type de Socket
CompressionOutputStream et CompressionInputStream
CompressionSocket et CompressionSocketServer
n Remarque
• Utilisé par les RMI pour personnaliser la couche Transport
au moyen de RMIClientSocketFactory/RMIClientSocketFactory
• voir jdk1.2.2\docs\guide\rmi\sockettype.doc.html
, 21
Personnaliser un type de Socket
Sous classe de Socket
import java.io.*; import java.net.*;
class CompressionSocket extends Socket {
private int compressionrate;
private InputStream in;
private OutputStream out;
public CompressionSocket(int compressionrate) {
super(); this.compressionrate=compressionrate;
}
Programmation Réseau en Java, D. Donsez, 1999-2000
, 23
Programmation UDP
en Java
Didier Donsez
Université de Valenciennes
Institut des Sciences et Techniques de Valenciennes
donsez@univ-valenciennes.fr
Les sockets en mode non connecté
n Principe
• l ’envoyeur (sender) envoie un datagramme (paquets de
données sur un socket que le receveur (receiver) écoute.
n La classe java.net.DatagramSocket
• Représente le socket local ou distant en mode non connecté
n La classe java.net.DatagramPacket
• Représente un packet (ou Datagramme) à envoyer ou reçu
, 27
Les sockets en mode non connecté
Utilisation
n Coté émetteur
• crée le DatagramSocket
DatagramSocket ms = new DatagramSocket(receiverInetAddress);
• construit un DatagramPacket
byte[] data = new byte[len]; // data doit être « rempli » : data = {'H', 'e', 'l', 'l', 'o'};
DatagramPacket outputPacket = new DatagramPacket(data, data.length, receiverInetAddress, port);
• envoie le DatagramPacket au recepteur
Programmation Réseau en Java, D. Donsez, 1999-2000
ms.send(outputPacket);
n Coté récepteur
• crée le DatagramSocket lié à un port d ’écoute
DatagramSocket theSocket = new DatagramSocket(port);
• construit un DatagramPacket pour la réception
byte[] incomingData = new byte[MAXLEN]; // buffer vide
DatagramPacket incomingPacket = new DatagramPacket(data, data.length);
• réception le DatagramPacket du paquet puis utilisation
theSocket.receive(incomingPacket);
, 28
Socket UDP
Déroulement de l ’exécution
hostsen hostrec
hostsen hostrec
JVM
JVMUDPSender
UDPSender JVM
JVMUDPReceiver
UDPReceiver
main thread main thread
Création d ’un DatagramSocket
Création d ’un DatagramSocket Création d ’un DatagramPacket
Création du DatagramPacket 1 Début d ’attente de réception d ’un
Envoi du DatagramPacket 1 DatagramPacket
, 29
Code du Emetteur
Exemple
import java.net.*; import java.io.*;
public class UDPSender {
public static void main(String[] args) {
try {
InetAddress receiver = InetAddress.getByName(args[0]);
int port = Integer.parseInt(args[1]);
DatagramSocket theSocket = new DatagramSocket();
DataInputStream userInput = new DataInputStream(System.in);
Programmation Réseau en Java, D. Donsez, 1999-2000
while (true) {
String theLine = userInput.readLine();
if (theLine.equals(".")) break;
byte[] data = new byte[theLine.length()];
theLine.getBytes(0, theLine.length(), data, 0);
DatagramPacket theOutput =
new DatagramPacket(data, data.length, receiver, port);
theSocket.send(theOutput);
}
} catch (Exception e) { System.err.println(e);}
}}
, 30
Code du Récepteur
Exemple
import java.net.*; import java.io.*;
public class UDPReceiver {
public static void main(String[] args) {
try {
// construction d'un DatagramSocket
int port = Integer.parseInt(args[0]);
DatagramSocket ds = new DatagramSocket(port);
// construction d'un DatagramPacket
Programmation Réseau en Java, D. Donsez, 1999-2000
, 33
Programmation MultiCast
en Java
Didier Donsez
Université de Valenciennes
Institut des Sciences et Techniques de Valenciennes
donsez@univ-valenciennes.fr
Utilisation des sockets
en mode diffusion restreinte (multicast)
n Rappel sur l ’IP MultiCast
• couche de transport non fiable en mode diffusion restreinte
• contrôle des erreurs mais pas de reprise sur erreur,
pas d ’ACK, séquencement des paquets non garanti
• utilisé pour les applications de diffusion restreinte
vidéo/audio-conférence, cours de bourse … lookup de JINI
Programmation Réseau en Java, D. Donsez, 1999-2000
• voir http://www.univ-valenciennes.fr/CRU/OR/
• UDP Unicast vs IP MultiCast
• UDP envoie un paquet de données
d ’un point (hôte) vers un autre (hôte,port)
• IP Multicast envoie une suite de paquets de données d ’un point (hôte)
vers un groupe d ’N hôtes qui souhaitent recevoir ces données
• Groupe MultiCast
• spécifié par une adresse de classe D (de 224.0.0.1 à 239.255.255.255)
• et par un port (UDP)
, 35
Utilisation des sockets
en mode diffusion multicast
n Principe
• le diffuseur (multicaster) rejoint un groupe multicast et envoie
un datagramme sur ce groupe
• les récepteurs (receiver) qui ont rejoint le groupe reçoivent les
datagrammes envoyés par les diffuseurs.
Programmation Réseau en Java, D. Donsez, 1999-2000
n La classe java.net.MulticastSocket
• dérive de java.net.DatagramSocket
• Représente le socket en diffusion
n La classe java.net.DatagramPacket
• Représente un packet (ou Datagramme) à envoyer ou reçu
, 36
Les sockets en mode diffusion restreinte
Utilisation
n Coté diffuseur
• crée le MulticastSocket
MulticastSocket ms = new MulticastSocket(); ms.joinGroup(groupInetAddress);
• construit un DatagramPacket d ’émission
byte[] data = new byte[len]; // data doit être « rempli » : data = {'H', 'e', 'l', 'l', 'o'};
DatagramPacket outputPacket = new DatagramPacket(data, data.length, groupInetAddress, port);
• envoie le DatagramPacket au groupe de diffusion
Programmation Réseau en Java, D. Donsez, 1999-2000
ms.send(outputPacket, ttl);
n Coté récepteur
• crée le MulticastSocket et rejoindre le groupe
MulticastSocket ms = new MulticastSocket(port); ms.joinGroup(groupInetAddress);
• construit un DatagramPacket de réception
byte[] data = new byte[len]; // data doit être « rempli »
DatagramPacket incomingPacket = new DatagramPacket(data, data.length);
• reçoit le DatagramPacket diffusé
ms.receive(incomingPacket);
, 37
Code du Diffuseur
Exemple
import java.net.*; import java.io.*;
public class MulticastSender {
public static void main(String[] args) {
try {
InetAddress ia = InetAddress.getByName(args[0]);
int port = Integer.parseInt(args[1]);
byte ttl = (byte)Integer.parseInt(args[2]);
MulticastSocket ms = new MulticastSocket();
Programmation Réseau en Java, D. Donsez, 1999-2000
ms.joinGroup(ia);
DataInputStream userInput = new DataInputStream(System.in);
while (true) {
String theLine = userInput.readLine(); if (theLine.equals(".")) break;
byte[] data = new byte[theLine.length()];
theLine.getBytes(0, theLine.length(), data, 0);
DatagramPacket dp = new DatagramPacket(data, data.length, ia, port);
ms.send(dp,ttl);
}
ms.leaveGroup(ia);
ms.close();
} catch (Exception e) { System.err.println(e); } } } , 38
Code du Receveur
Exemple
import java.net.*; import java.io.*;
public class MulticastReceiver {
public static void main(String[] args) {
try {
// paquet de réception
byte[] buffer = new byte[65509];
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
Programmation Réseau en Java, D. Donsez, 1999-2000
while (true) {
ms.receive(dp);
String s = new String(dp.getData(), 0, 0, dp.getLength());
System.out.println(s);
}
} catch (Exception e) { System.err.println(e); }
}} , 39
Remarques sur MulticastSocket
, 40
Remarques sur le Time-To-Live
R R
R3
R2
D R0 R1 R5 R5
R R R R
R2 R2
, 41
Les classes de Connexion
java.net.URL
java.net.URLConnection
Didier Donsez
Université de Valenciennes
Institut des Sciences et Techniques de Valenciennes
donsez@univ-valenciennes.fr
java.net.URL
n Utilitaires
static String URLDecoder.decode(String urlencoded)
static String URLEncoder.encode(String str)
• méthodes statiques de conversion
x-www-form-urlencoded vers/depuis String
, 45
java.net.URL
Exemple de récupération d ’un document
import java.net.*;
import java.io.*;
public class URLReader {
public static void main(String[] args) throws Exception {
URL aurl = new URL(args[0]);
BufferedReader in = new BufferedReader(
Programmation Réseau en Java, D. Donsez, 1999-2000
new InputStreamReader(aurl.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) System.out.println(inputLine);
in.close();
}
}
, 46
La classe de connexion
java.net.URLConnection
n Définit une connexion à une URL
• superclasse abstraite indépendante du schéma de connexion
(http, ftp, file, mailto, …)
Programmation Réseau en Java, D. Donsez, 1999-2000
n Sous-classes
• HttpURLConnection, JarURLConnection
, 47
java.net.URLConnection
n Utilisation
• 1- l ’instance est récupéré de URL.openConnection()
• 2- configuration des paramêtres de la connexion
•setAllowUserInteraction, setDoInput, setDoOutput, setIfModifiedSince,
setUseCaches, setRequestProperty
Programmation Réseau en Java, D. Donsez, 1999-2000
, 48
java.net.URLConnection
Exemple de récupération d ’un document
import java.net.*;
import java.io.*;
public class URLConnectionReader {
public static void main(String[] args) throws Exception {
URL aurl = new URL(args[0]);
URLConnection aurlcnx = aurl.openConnection();
BufferedReader in = new BufferedReader(
Programmation Réseau en Java, D. Donsez, 1999-2000
new InputStreamReader(aurlcnx.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) System.out.println(inputLine);
in.close();
} }
n Exercice :
• écrire un robot qui récupère une hiérarchie de documents HTML
à partir d ’une URL
, 49
java.net.URLConnection
Exemple d ’envoi de mail
import java.net.*;
import java.io.*;
public class MailSender {
public static void main(String[] args) throws Exception {
URL mailto = new URL("mailto:"+args[0]);
URLConnection mailtocnx= mailto.openConnection();
mailtocnx.connect();
Programmation Réseau en Java, D. Donsez, 1999-2000
, 50
java.net.HttpURLConnection
, 51
java.net.HttpURLConnection
Exemple de récupération d ’un document
import java.net.*; import java.io.*;
public class HttpURLConnectionReader {
public static void main(String[] args) throws Exception {
URL httpurl = new URL(args[0]);
HttpURLConnection httpcnx = (HttpURLConnection)httpurl .openConnection();
if(httpcnx.getResponseCode()== HttpURLConnection.HTTP_OK) {
Programmation Réseau en Java, D. Donsez, 1999-2000
, 52
java.net.JarURLConnection
• Gestionnaire de schéma
• sous-classe de URLStreamHandler
• par défaut sun.net.www.protocol.<schema>.Handler
• Gestionnaire de connexion
• sous-classe de URLConnection
• Gestionnaire de contenu (type/soustype MIME)
• sous classe de ContentHandler
• par défaut : sun.net.www.content.<type>.<soustype> , 54
Les gestionnaires pour URL
• Gestionnaire de schéma
Programmation Réseau en Java, D. Donsez, 1999-2000
• setURLStreamHandlerFactory(URLStreamHandlerFactory factory)
• Gestionnaire de contenu (type/soustype MIME)
• setContentHandlerFactory(ContentHandlerFactory factory)
, 55
Conclusion
, 58
Bibliographie
Programmation des Sockets
n Voir le cours « Socket sous Unix »
n Scott Oaks, Henry Wong, "Java Threads", 2nd Edition,Ed Oreilly, 1999, 1-
56592-418-5, existe en français
• voir Chapitre 5 pour les serveurs multithreadés
n David Flanagan, « Java in a Nutshell », Oreilly
n E.R Harold, "Java I/O", Ed Oreilly, 1999, 1-56592-485-1
• voir Chapitre 5 pour l ’utilisation de Input/Output streams
n Robert Orfali, Dan Harkey, “Client/Server Programming with Java and Corba ”,
2ème édition, 1998, Ed Wiley, ISBN 0-471-24578-X.
• voir le chapitre 10 qui compare les Sockets à CORBA , 59