Académique Documents
Professionnel Documents
Culture Documents
appliquée avec le langage Java
Le langage Java – Partie 1
IUT d'Aix‐Marseille
Réseaux et Télécommunications La programmation orientée objet
Novembre 2013
Ivan Madjarov
IvMad, 2008-2013 2
Les notions de l'Objet Le modèle Java
• Introduction au modèle Java
• La Programmation Orientée Objet
• Objets et Classes
• Propriétés et Méthodes
• Encapsulation
• Constructeurs et Destructeurs
• Surcharge et Redéfinition
• Héritage
• Polymorphisme
IvMad, 2008-2013 3 IvMad, 2008-2013 4
Java ‐ Introduction Java ‐ Modèle VM
• La portabilité de Java
La programmation orientée objet La programmation orientée objet
• Le modèle Objet: • Les objectifs de la POO
– Considère que le monde est composé d’objets – Faciliter la réutilisation de code, encapsulation et
– Les objets sont identifiables individuellement. abstraction.
– Les objets sont en relation avec d’autres objets – Faciliter l’évolution et l’extension du code.
– Les objets peuvent être abstraits sous la forme de – Améliorer la conception et la maintenance des grands
"types" que l’on appelle classes systèmes.
– Les classes sont organisées sous la forme d'hiérarchies – Programmation par "composants".
– Penser en termes d'abstractions conceptuelles • Conception d’un logiciel à la manière de la fabrication
– Penser en termes d'entités relativement autonomes d’une voiture par modules fabriqués par des sous‐
traitants.
– Penser en termes de cadres (frameworks) et de
composants réutilisables
La programmation orientée objet La programmation orientée objet
• La structure de la classe Java • Visibilité des attributs dans la classe
class Nom_Classe {
Attribut(s) de la classe;
Méthode(s) de la classe;
Méthodes des attributs privés Mot‐clé static
// accesseurs pour lecture //modificateurs pour écriture • Placé devant une propriété ou une méthode
– Exemple : static int count = 0;
public String getPrenom() { public void setPrenom(String P) {
this.prenom=P; – Exemple : static Circle bigger(Circle c1, Circle
return prenom; } c2) {..}
} • Effet: Il n'est pas nécessaire d'instancier la classe pour accéder à
public void setNom(String N) { ses membres statiques (de l’extérieur d’une classe on peut faire
public String getNom() { this.nom=N; directement Nom_classe.nom_statique)
return nom; }
– Les propriétés static sont communes à toutes les instances
} public void setAge(int A) { de la classe
this.age=A; – Les méthodes static sont l’équivalent aux fonctions en C
public int getAge() { }
• Les méthodes statiques ne peuvent pas accéder à this
return age;
} • Les membres statiques sont accessibles via la classe
Partie II Héritage
• L’objectif de l’héritage est de construire de nouvelles
classes en réutilisant les attributs et les méthodes de
L'Héritage classes déjà existantes.
• Les attributs et les méthodes peuvent être modifiés au
niveau de la sous‐classe.
• Il peut y avoir des attributs et/ou des méthodes
supplémentaires dans une sous‐classe.
– Une classe B qui hérite d’une classe A dispose implicitement
de tous les attributs et de toutes les méthodes définis dans A
– Les attributs et les méthodes définis dans B sont prioritaires
par rapport aux attributs et aux méthodes de même nom
définis dans A.
Les objets temporaires
• Dans une expression, on peut faire appel explicitement au
constructeur d'une classe : l'objet est construit, mais nous
n'y avons pas accès pour le modifier par exemple.
• L'espace mémoire qu'il occupait sera automatiquement
récupéré ultérieurement par un programme appelé
"ramasse‐miettes " dont le rôle est de récupérer l'espace
mémoire occupé par des objets qui ne sont plus référencés
par des données du programme.
IvMad, 2008-2013 43
Programmation orientée objet
appliquée avec le langage Java
La programmation orientée objet avec le langage Java – Partie 2
http://139.124.26.245/java et sur AmeTice
IUT d'Aix‐Marseille JAVA
Réseaux et Télécommunications PACKAGES, EXCEPTION,
Novembre 2013
STRING, STREAM
Ivan Madjarov
IvMad, 2008-2013 2
Sommaire Partie III
• Les Exceptions
• Les APIs
• String Les Exceptions
• Stream
• Fichiers
• Classes abstraites
• Polymorphisme
• Interfaces
La gestion des exceptions La gestion des exceptions
• Ce sont des instances de classes dérivant de • Exemple du séquencement :
java.lang.Exception
• La levée d'une exception provoque une remontée
dans l'appel des méthodes jusqu'à ce qu'un bloc Object getContent()
{
try 1
catch acceptant cette exception soit trouvé {
openConnection(); void openConnection()
} throws IOException
• Si aucun bloc catch n'est trouvé, l'exception est 7
catch(IOException e) {
...
{
openSocket(); 4 2
capturée par l'interpréteur (JVM) qui l’affiche et le
}
6 sendRequest();
void sendRequest()
finaly {
... 5 }
receiveResponse();
throws IOException
{
programme s'arrête. }
...
write(header);
write(body); //ERREUR
}
8 }
• Un bloc optionnel finally peut‐être posé à la suite des 3
catch. Son contenu sera exécuté qu’il ait eu une
exception ou pas.
Partie IV Les API java: java.lang.String
• La classe String gère des chaînes de caractères .
• Une String n’est pas modifiable.
Les String • Toute modification entraine la création d'une
nouvelle String.
(Chaîne de caractères) • Les valeur littérales ("abc") sont transformées en
objets String.
• L'opérateur “+” permet la concaténation de 2 String
– EX: ("abc"+"def" ‐‐>"abcdef" )
java.lang.StringBuffer La méthode toString()
• La classe StringBuffer gère des chaînes de caractères • La méthode toString est définie dans la classe Object
(char) modifiable (setCharAt(), append(), insert())
• La méthode toString() convertie une StringBuffer en dont toutes les classes Java en hérite.
String (fige la valeur: moins gourmand en mémoire) • Lorsqu'on définit une classe, il est utile de redéfinir la
StringBuffer sb = "abc"; // Erreur: can't convert String to StringBuffer
méthode toString afin de donner une description
StringBuffer sb = new StringBuffer("abc"); // OK
satisfaisante des objets de cette classe.
sb.setCharAt(1, 'B'); // sb= "aBc"
• Quand on redéfinit la méthode toString, on fait en sorte
sb.insert(1, "1234);
sb.append("defg");
// sb = "a1234Bc"
// sb = "a1234Bcdefg"
qu'elle renvoie une chaîne de caractères servant à
décrire l'objet concerné.
String s = sb.toString(); // s = "a1234Bcdefg"
sb.append("hij"); // sb = "a1234Bcdefghij" – public String toString();
// s = "a1234Bcdefg"
Les packages: import Les core API
• Les API les plus courant:
• les noms complets des classes sont :
nom_du_package.nom_de_la_classe; – java.lang : Types de bases, Threads, Exception, Math, ...
– java.util : Hashtable, Vector, Stack, Date, ...
ou encore
– java.applet : Interface vers les applications Web
package.souspackage.classe;
– java.awt : Interface graphique portable
• pour utiliser des classes sans les préfixer du nom de leur package – java.io : accès aux i/o par flux (fichiers, stdin, stdout,..)
il faut : – java.net : Socket (UDP, TCP, multicast), URL, ...
– import package.souspackage.classe; – java.lang.reflect : introspection sur les classes et les objets
– import package.*; (TOUTE les classes) – java.beans : composants logiciels
– java.sql (JDBC) : accès homogène aux bases de données
• Exemple: – java.security : signature, cryptographie, authentification
– import java.io.File; // une seule classe – java.rmi : Remote Method Invocation
– import java.io.*; // toutes les classes • les API sont installées en version binaire
• le "*" n ’est pas récursif ! – utilisables via la javadoc associée (au format HTML)
– A télécharger en même temps que le JDK!
• Implicite dans un prog.java : import java.lang.*;
IvMad, 2008-2013 19 IvMad, 2008-2013 20
Les core API et la Javadoc Les core API et la Javadoc
• La documentation des API de Java est en ligne à : Exemple de la javadoc des API:
Description de la
– http://java.sun.com ou http://www.javasoft.com classe en cours
– Accès direct à l ’API v1.6:
• http://java.sun.com/j2se/1.6/docs/api/
Nom
• Format de la javadoc (dans le navigateur):
Packages A C Description de
(filtre sur les la classe en
classes) cours
B Nom (selectionnée
Classes de l ’API
Description dans B)
(par ordre description
Propriétés
alphabetique)
Constructeurs méthodes
Classes de l ’API
Méthodes (par ordre
alphabetique)
Packages personnalisés Packages personnalisés
• L'arborescence des répertoires contenant les classes doit être identique à
• L'instruction package indique à quel package l'arborescence des packages
appartient la ou les classe(s) du fichier. – les noms des packages/répertoires sont case sensitifs
– par défaut le package anonyme est le repertoire courant
• package doit être la première instruction du fichier
• Une classe Circle appartenant au package Forme.2D doit se trouver
source dans le fichier Forme/2D/Circle.class
• Par défaut (si pas d'instruction package dans le fichier) sources packages répertoires
Les API java: java.util.* Les API java: java.util.Vector
• Cette classe gère une collection d'objets dans un tableau de
taille dynamique à l'opposé du tableau [] qui a la taille fixe!
BitSet • Inconvénients:
Date – plus gourmand en mémoire qu’un tableau[]
Dictionary Hashtable Properties – plus lent également
Object – ne gère que des objets (pas de types primitifs)
Observable
– mais permet l’hétérogénéité des elements
Random
• Exemple:
StringTokenizer Vector v = new Vector();
Vector Stack v.add(new Personne()); // élément 0
v.add(new date()); // élément 1: date du jour
v.add(1, new String("abcde")); // nouvel élément 1
v.add(new Vector()); // un sous-vecteur!
System.out.println(v.size()+v.elementAt(2));// 4abcde
Partie VI Le modèle I/O Stream
• Pour accéder à une information donnée, un
programme ouvre un flux vers la source d'information
(un fichier, mémoire, réseau etc.) et lie cette
Les Stream IO information de manière séquentielle.
• Pour écrire une information donnée, un programme
(les flux E/S) ouvre un flux vers la sortie et la aussi, il écrit de
manière séquentielle cette information sur le support
d'écriture (fichier, mémoire, réseau etc.)
• Le modèle des flux:
Données entrantes Données sortantes
Programme
Le modèle Stream Les flots d'entrée‐sortie
– Flux binaire: sert à lire/écrire des informations codées • Résumé:
en iso‐latin‐1 sur 8 bits. Contient les superclasses: • La communication d’une application Java avec le
• InputStream
monde extérieur s’effectue par des Stream (flots):
– int read();
– int read(byte cbuf[]); – Flots de données binaires (bytes)
– int read(byte cbuf[], int offset, int length); – Flots de caractères (char)
• OutputStream • Quel que soit la communication établie (fichiers ou
– int write(int c);
réseau) et le type de données transportée (Unicode ou
– int write(byte cbuf[]);
– int write(byte cbuf[], int offset, int length);
binaire), la procédure générale consiste à :
1. ouvrir un flot ("Stream") de communication ;
2. utiliser le flot pour lire ou écrire des données ;
3. fermer le flot de communication.
• Méthode readLine(); pour lire au clavier un String SequenceInputStream
File StringBufferInputStream
– BufferedWriter : Écriture de texte dans un flux de sortie Object
(caractères, tableaux et chaînes de caractères).
Accès en R/W et
RandomAccessFile
– DataInputStream : Lecture de données Java primitives. positionnement
Stream buffer Stream buffer
• Exemple: • Lire un String et un entier au clavier:
BufferedReader IN = new BufferedReader( new public static void main(String[] args) {
InputStreamReader(System.in)); BufferedReader IN = new
BufferedReader(new InputStreamReader(System.in));
String ligne = null; String nom = null;
try{ int age = 0;
ligne = IN.readLine(); // Lire une ligne au clavier try {
System.out.println("Nom: ");
} catch (Exception e){
nom = IN.readLine();
System.err.println(e); System.out.println("Age: ");
System.exit(2); age = Integer.parseInt(IN.readLine());
} System.out.println("Votre nom est "+nom+" et vous avez
"+age+" ans");
– e est un objet dérivé du type Exception. } catch (Exception e){
System.err.println(e);
– IOException, SecurityException, ArithmeticException, }
etc… }
Lire un fichier texte Écrire un fichier texte (1)
String chaine=""; String s = "Le message à enregistrer dans un fichier";
String fichier="source.txt"; BufferedWriter bfWr = null;
try { try {
// Ouvrir le fichier // Construire un objet de type BufferedWriter
InputStream ips = new FileInputStream(fichier); bfWr = new BufferedWriter(new FileWriter("fichier.txt"));
// Initialiser le flot de lecture // Ecrire la chaine à la sortie Stream
InputStreamReader ipsr = new InputStreamReader(ips); bfWr.write(s);
// Unité de lecture // Ecrire une fin de ligne
BufferedReader br = new BufferedReader(ipsr); bfWr.newLine();
String ligne=""; } catch (IOException ex) { ex.printStackTrace();
// Lire les lignes du fichier } finally { // Fermer BufferedWriter
while ((ligne = br.readLine()) != null) { try {
chaine += ligne+"\n"; if(bfWr != null) {
} bfWr.flush(); // vider et fermer le buffer
br.close(); bfWr.close(); }
} catch (Exception e){ System.err.println(e.getMessage()); } catch (IOException ex) { ex.printStackTrace(); }
} }
Les flux (Stream) Les flux (Stream)
• java.io.Data permet de lire et d'écrire des types • java.io.PrintStream permet de manipuler un
primitifs et des lignes sur des flux. OutputStream au travers des méthode print() et
FileInputStream fis = new FileInputStream("source.dat"); println().
DataInputStream dis = new DataInputStream(fis);
• PrintStream ps = new PrintStream(new
int i = dis.readInt(); FileOutputStream("cible.txt", true));
double d = dis.readDouble();
String s = dis.readLine(); • Le paramètre "true" autorise l'ajout de nouvelles lignes
FileOutputStream fos = new FileOutputStream("cible.dat"); à la fin du fichier "cible.txt".
DataOutputStream dos = new DataOutputStream(fos); – ps.println("Une ligne");
dos.writeInt(123);
– ps.println("Une deuxième);
dos.writeDouble(123.456);
– ps.print("Une autre ligne");
dos.writeChars("Une chaine");
– ps.print("123 et fin");
– ps.flush();
– ps.close();
Classes concrètes
et terminales
Classes abstraites Classes abstraites
• Les classes abstraites constituent le cœur des • Les classes abstraites (prototype)
applications Java – Une classe est dite abstraite si elle ne fournit pas
d'implémentation pour certaines de ces méthodes
Compte bancaire Classe abstraite et non-terminale qui sont dites méthodes abstraites et ainsi ne peut
avoir d'instance.
Compte Compte Classes concrètes
– Il appartient à ces classes dérivées de définir du code
courant d'épargne et terminales pour chacune des méthodes abstraites. On parlera
alors de classes concrètes qui peuvent être
Méthodes de classe instanciées.
– Le but est de définir un cadre pour les classes
dérivées en proposant un ensemble de méthodes
pour toute l'arborescence.
IvMad, 2008-2013 51 IvMad, 2008-2013 52
Mot‐clé abstract Classes abstraites
• Une méthode est dite abstraite si on ne veut écrire que le • Une classe abstraite est une classe qui ne peut pas
prototype (la "signature" pas le corps). avoir d'instance
• Si dans une classe, au moins une méthode est déclarée – Comporte des méthodes abstraites éventuellement
abstract, alors la classe devient abstraite.
• L’implémentation (le corps) de la méthode s’effectuent • En Java une méthode abstraite est une méthode qui
dans les classes qui héritent de cette classe. n'a pas de code. A distinguer des méthodes vides qui
• Pour ne plus être abstraite, une classe fille doit ne font rien…
implémenter toutes les méthodes abstraites de la classe abstract void p(); // est abstraite
dont elle hérite. void p(){} // méthode vide, ne fait rien..
• Si une classe est déclarée abstract, alors elle ne peut pas – Une classe abstraite peut contenir des attributs et des
être instanciée. méthodes
abstract class C1 { class C2 extends C1{
abstract void methode( ); void methode( ){
void normale( ){ // corps de la méthode
// corps de la méthode }
} }
}
Classes abstraites Classes abstraites
• Une forme géométrique est une classe abstraite abstract class Forme {
// nom de la forme
• Chaque forme géométrique peut être spécialisée en: private String nom;
– Carré // Constructeur
– Cercle public Forme(String N) {
– Rectangle this.nom = N;
}
– Ellipse
public String getNom() {
• Pour toutes les formes géométriques on peut calculer: return nom;
– L'aire }
– Le périmètre // Méthodes communes à chaque forme
abstract double aire(); // Calcule l'aire
• Si Forme est la classe abstraite, le calcul de l'aire et du abstract double perimetre(); // et le périmètre
périmètre sont des méthodes abstraites. }
Interfaces Interfaces
• L'héritage multiple • L'héritage multiple est délicat d'utilisation
– Une classe qui possède plusieurs classes mères afin • En C++, il y a de l'héritage multiple possible
de modéliser une généralisation multiple. • En Java, il n'y a pas d'héritage multiple
– Exemple: on souhaite ajouter la classe Hovercraft à • Pour palier à cette situation, Java dispose d'une classe
notre modèle de parc de véhicules. particulière
Un Hovercraft est à – L'interface est déclarée avec le mot clé interface.
la fois un bateau et
– Il s'agit d'une classe dont toutes les méthodes sont
un véhicule terrestre.
abstraites et publiques et tous les attributs sont
constants.
– Une classe n'hérite pas d'une interface mais elle
l'implémente à l'aide du mot clé implements
IvMad, 2008-2013 63 IvMad, 2008-2013 64
Programmation orientée objet
appliquée avec le langage Java Partie X
Programmation objet avec Java
• Application et Applet
IUT d'Aix‐Marseille • Dessiner avec une Applet
Réseaux et Télécommunications
Novembre 2013
Ivan Madjarov
IvMad, 2002-2013 2
Application et Applet Applet objet téléchargeable
• Une application Java est un programme "Standalone" •
c.à.d. à part entière. Pour l'exécuter on a besoin d'une
JVM installé dans un système d'exploitation.
• Un programme compilé, accessible par un serveur Web
et téléchargé pour être exécuté par un navigateur Web
sur sa propre JVM est une applet.
• Ainsi les applets se présentent comme des objets
téléchargeables ou applications Web.
• Pour assurer la sécurité des systèmes les applets sont
soumis à des restrictions d'accès!
– Une applet n'accèdent pas aux système de fichiers locaux.
Les applets Java Les applets Java
• Une applet dérive de la classe Applet et redéfinit
tout ou en partie quatre fonctions de base. • Exemple d’applet :
import java.awt.*;
• Le code "standard" d’une applet: import java.applet.*;
import java.applet.*; public class helloApplet extends Applet {
public class uneApplet extends Applet { public void paint(Graphics g) {
public void init() {
// afficher un texte aux coordonnées x=50px, y=20px
// code d'initialisation g.drawString("Bonjour tout le monde!",50,20);
} }
public void start() { }
// code de l'exécution
}
public void stop() {
// code de suspension de l'exécution
}
public void destroy() {
// code de terminaison
} }
IvMad, 2002-2013 7 IvMad, 2002-2013 8
Les applets Java Les applets Java par JCreator
• L’utilisation de l’applet ce fait à partir d’un document • Exécution:
HTML: – Une Applet est un fichier classe appelé par le navigateur
– On défini le nom de la classe et la taille du cadre dédié Web à travers un fichier HTML.
à l'applet. • Pour créer une Applet dans JCreator:
<!DOCTYPE HTML> – File ‐> New File ‐> Java Classes ‐> Applet Classe ‐> Next ‐>
<html> Name ‐> Location
<head>
</head>
– Rédiger le code de l'applet suivant le sujet du TP
<body> – Sauvegarder et compiler par "Build File"
<applet • Pour créer le fichier HTML qui exécute l'Applet:
code = "helloApplet.class" – File ‐> New File ‐> Other‐> HTML Applet ‐> Next ‐> Name ‐
width = "250" > Location
height = "100" >
– Préciser le nom de la classe sur la ligne:
</applet>
code = "helloApplet.class" et la taille du cadre d'affichage
</body> par les "width" et " height" en pixels.
</html>
– Sauvegarder et exécuter le fichier par le menu "Run File"
IvMad, 2002-2013 9 IvMad, 2002-2013 10
Les applets Java avec Eclipse Dessiner dans une Applet
• Sous Eclipse la rédaction d'une applet ne diffère pas
de la création d'une application Java. • Méthodes de tracé graphique
– On crée un projet Java; – Pour tracer des cercles et des ellipses:
– On ajoute au projet une classe Java qui hérite de la • drawOval(int x, int y, int width, int height);
classe Applet; – Pour tracer des carrés et des rectangles:
– On rédige le contenu de l'applet; • drawRect(double x, double y, double longueur,
– On sauvegarde le code de l'applet; double largeur);
– On exécute l'applet avec appletviewer: – Un hexagone on peut tracer à partir de la méthode
• select Run‐>Run as‐>Java Applet from the menu bar graphique
• drawPolygon(int[] xPoints, int[] yPoints,
int nPoints);
– Pour tracer un texte à l'écran:
• drawString(String s, int x, int y);
Introduction
• Le modèle OSI (Open System Interconnexion)
Partie XI
Programmation réseau en Java
Routage
Couches réseau Package Java
• Trame <‐> Datagramme <‐> Transport <‐> Application • Le package java.net contient toutes les classes
orientées réseau bas niveau de l'API JAVA.
La Socket Les ports
• Le rôle des Sockets: • Un service réseau rendu par un programme serveur sur
– Connexion à une machine distante une machine est accessible par un port
– Envoie/Réception de données • Un port est identifié sur une machine par un nombre
– Fermeture d'une connexion entier (16 bits)
– Attachement à un port • Les numéros de port de 0 à 1023:
– ports réservés aux services standard assignés par l'IANA
– Acceptation d'une demande de connexion à un port
(Internet Assigned Numbers Authority)
local
• A un port est attribué un numéro allant de 1 à 65535
• Les ports de 1 à 1023 sont réservés aux services:
– FTP (21), HTTP (80), SMTP (25)
– Attente de demandes de connexion
• Les numéros de port supérieur à 1024 sont disponibles
pour placer un service applicatif défini par l'utilisateur.
IvMad, 2002-2013 23 IvMad, 2002-2013 24
Processus de Socket Le processus Socket
Source Christine Bulfone : Le client/serveur et l’API socket Selon les transparents de Rémy Courdier
Le processus Socket Le processus Socket
Selon les transparents de Rémy Courdier Selon les transparents de Rémy Courdier
Selon les transparents de Rémy Courdier Selon les transparents de Rémy Courdier
Le processus Socket
Partie XII
Programmation réseau en Java
par Socket en mode non connecté :
Le protocole UDP (RFC 768)
(User Datagram Protocol)
Mode datagramme (UDP) Mode datagramme (UDP)
• Le principe de la programmation réseau en mode • Pour recevoir des datagrammes en Java il faut suivre
datagramme en Java se base: les étapes suivantes :
– (1) sur l'envoie des datagrammes – Créer une instance de la classe DatagramSocket qui
– (2) la reception des datagrammes. attend l’arrivée de données par le réseau.
• Pour envoyer des datagrammes en Java on suit les – Créer une instance de la classe DatagramPacket qui
étapes suivantes : reçoit les données par l’instance de DatagramSocket.
– Obtenir l’adresse du destinataire et la mettre dans une
instance de la classe InetAddress.
– Mettre les données et l’adresse dans une instance de la
classe DatagramPacket.
– Créer une instance de la classe DatagramSocket et lui
confier l’envoi du datagramme.
IvMad, 2002-2013 35 IvMad, 2002-2013 36
Mode datagramme (UDP) Mode datagramme (UDP)
• La classe DatagramPacket fournit deux constructeurs : • Trouver l’adresse IP correspondant à un nom de machine
– un pour les paquets à recevoir,
– l'autre pour les paquets à envoyer. import java.net.*;
import java.io.*;
1. Construire un objet pour recevoir un datagramme.
– public DatagramPacket(byte buffer[], int taille) public class ResoudreNom {
‐ buffer correspond à la zone de réception public static void main(String[] args) {
‐ taille maximale des datagrammes à recevoir. InetAddress adresse;
Les données reçues au delà de la taille de la zone de stockage sont perdues try {
2. Construire un objet pour envoyer un datagramme. adresse = InetAddress.getByName(args[0]);
– public DatagramPacket(byte buffer[], int taille, System.out.println("Nom : "+args[0]+", IP: "
InetAddress adresse, int port) + adresse.getHostAddress());
} catch(UnknownHostException e) {
‐ buffer correspond à la zone d'envoie System.err.println(args[0]+" est inconnu\n");
‐ taille correspond à la taille du datagramme à envoyer }
‐ adresse destinataire de la datagramme }
‐ port du UDP }
Mode datagramme (UDP) Émetteur UDP
• Deux programmes pour illustrer le mode datagramme: • En première on résout le nom de la machine destinatrice
– Le programme "Emetteur" permet l’envoi vers le programme (passé en argument) en adresse réseau.
"Recepteur" des messages par le réseau. – adr = InetAddress.getByName(args[0]);
• Ensuite une chaîne de caractères est transformée en suite
d’octets pour les transmettre sur le réseau.
– String message =
– Le programme "Recepteur" se charge d'afficher le message "Démonstration du mode datagramme";
reçu. – byte[] tampon = new byte[message.length()];
• Un tableau de byte est créé à la taille du message.
• Une transformation en byte se fait par la méthode
getBytes() de la classe String.
– tampon = message.getBytes();
Récepteur UDP Récepteur UDP
import java.io.*;
• Une zone mémoire tampon pour recevoir les données. import java.net.*;
public class Recepteur {
– byte[] tampon = new byte[200]; int port; // Le port pour la réception
byte[] tampon; // Tableau de byte pour recevoir les données de l'émetteur
• Ensuite nous créons un DatagramSocket pour écouter DatagramPacket paquet; // Réception en créant le packet datagramme
DatagramSocket sock; // Socket sur le port de réception
sur le port de destination en attente de données. String message;
public Recepteur (int n) { // Constructeur qui prend le numéro du port en attribut
– DatagramSocket sock = new DatagramSocket(port); try {
port = n; // affectation du port d'écoute
• L’ordre d’attente se fait par la méthode receive() tampon = new byte[200]; // définir le tableau de type byte
paquet = new DatagramPacket(tampon, tampon.length); // créer l'objet de type packet
– sock.receive(paquet); sock = new DatagramSocket(port); // créer la Socket
sock.receive(paquet); // écoute du port de réception
• La méthode se charge de placer les données dans un message = new String(tampon); // Conversion des octets en chaine
System.out.println(message.toUpperCase()); // Afficher le message
DatagramPacket gérant le tampon. } catch(SocketException e) { System.err.println("Erreur de Socket " + e);
} catch(IOException e) { System.err.println("Erreur d'Entrée‐Sortie " + e); }
– DatagramPacket paquet = new }
DatagramPacket(tampon, tampon.length); public static void main(String[] args) {
new Recepteur(1025); } } // créer l'objet anonyme du récepteur
Un transparent
du cours
d'Etienne Duns
IUT d'Aix‐en‐Provence
Réseaux et Télécommunications
Décembre 2013
Ivan Madjarov
IvMad, 2002-2013 2
Mode TCP et UDP Le mode connecté (TCP)
• Fonctionnement en mode connecté
– Données envoyées dans un "tuyau" et non pas par paquet
– Flux de données (Stream)
– Fiable : la couche TCP assure que:
• Les données envoyées sont toutes reçues par la machine
destinataire
• Les données sont reçues dans l'ordre où elles ont été envoyées
Le mode connecté (TCP) Les Sockets (connecteurs réseau)
• Le Client et le Serveur en mode connecté • Une application Client se connecte par une adresse IP
sur un numéro de port.
• Le serveur accepte la connexion et fournit une nouvelle
socket avec un nouveau port de communication pour
continuer à écouter sur la socket originale.
• Du côté du client, si la connexion est acceptée, une
socket est créée pour assurer la communication avec le
serveur.
IvMad, 2002-2013 7 IvMad, 2002-2013 8
Les Sockets (connecteurs réseau) Les Sockets (connecteurs réseau)
• Classe java.net.Socket propose: • Mise en œuvre du modèle Client‐Serveur:
– Méthodes d'émission et de réception de données – La Socket est créé sur le client.
– Contrairement aux sockets UDP, les sockets TCP n'offre pas – Le ServerSocket fonctionne sur le serveur en attente de
directement de services pour émettre‐recevoir des données connexion ( méthode accept() ).
• On récupère les flux d'entrée‐sorties associés à la socket – La Socket tente de se connecter sur le serveur distant.
OutputStream getOutputStream()
– Connexion établie, le ServerSocket génère une Socket pour
• Retourne le flux de sortie permettant d'envoyer des données communiquer avec le client.
via la socket InputStream getInputStream()
– La connexion établie, le système Client et Serveur établit un
• Retourne le flux d'entrée permettant de recevoir des données
via la socket
canal de communication par flux à partir de leur Sockets pour
échanger des données.
– Fermeture d'une socket
• public close()
– Après fin des échanges, l'un des interlocuteurs clôt le canal
de communication.
• Ferme la socket et rompt la connexion avec la machine distante
Les Sockets (connecteurs réseau) Les Sockets (connecteurs réseau)
• Constructeurs: – public inputStream getInputStream() throws
IOException : retourne le flux d'entrée associé à la socket.
– public Socket(String host, int port) throws
UnknownHostException, IOException; – public OutputStream getOutputStream() throws
IOException : retourne le flux de sortie associé à la socket.
– public ServerSocket(int port) throws IOException;
– public void close() throws IOException : ferme la
• Méthodes: ServerSocket.
– host (String) : nom de la machine vers laquelle la socket est créée. – public Socket accept() throws IOException : place le
ServerSocket en attente de requête d'ouverture de socket.
– addresse (InetAddress) : adresse IP de la machine vers laquelle la
socket est créée. • Cette attente est bloquante. Une socket est
– port (int) : numéro du port sur lequel la socket est créée. automatiquement générée et retournée lors de cette
– localAddr (InetAddress) : adresse IP locale à la quelle la socket est requête.
associée.
– localPort (int) : numéro du port local auquel la socket est associée.
– public void close() throws IOException : ferme la socket.
Serveur d'heure TCP Le Client TCP
import java.net.*; import java.io.*; import java.util.*; // Client cherchant l'heure sur le serveur
class serveurHeure { // Retourne au client la date et l'heure import java.io.*; >java ClientTCPHeure
public static void main(String args[]) { import java.net.*; Wed Nov 25 08:58:32 CET 2013
try { public class ClientTCPHeure { >
// Installer le serveur sur un port public static void main(String args[]) {
ServerSocket sks = new ServerSocket(8181); String ligne = "";
System.out.println("Serveur en attente"); try {
// Tourne en attente de connexion // Etablir une connexion TCP sur un port
Socket sk = sks.accept(); Socket sk = new Socket("localhost",8181);
System.out.println(sk.toString()); // Le flux d'entrée pour recevoir le message serveur
DataOutputStream out = new BufferedReader is = new BufferedReader(new
DataOutputStream(sk.getOutputStream()); InputStreamReader(sk.getInputStream()));
out.writeBytes(new Date()+"\n"); // ecr. date et heure // Lire le flux d'entrée
sk.close(); while ((ligne = is.readLine()) != null)
>java serveurHeure
sks.close(); Serveur en attente System.out.println(ligne); // message du serveur
} catch (IOException e) { Socket[addr=/127.0.0.1,port=49409,localport=8181]
} catch (Exception e) {
System.out.println(e.getMessage()); System.err.println(e.getMessage()); }
} }
} } }
IvMad, 2002-2013 15 IvMad, 2002-2013 16
Le client TCP émet un message Serveur TCP traite le message
import java.net.*; import java.net.*;
import java.io.*; import java.io.*;
public class ClientTCP { public class ServeurTCP {
Socket sock = null; int port = 1500; // Port de connexion
public ClientTCP(String host, int port, String data) { ServerSocket SkS; // La socket serveur
try { Socket SkC; // La socket client
// Connexion sur le port du serveur BufferedReader input; // Lecteur du flux d'entrée
sock = new Socket(host, port); String message;
// Définir le flux de sortie public ServeurTCP() { // Constructeur de la classe
PrintStream output = new try {
PrintStream(sock.getOutputStream());
// La socket serveur est installée sur le port 1500
output.println(data); // Envoi des données
SkS = new ServerSocket(port);
sock.close();
System.out.println("Serveur sur port: " + SkS.getLocalPort());
} catch(IOException e) { }
// Serveur en attente infinie:
}
(1) connexion d'un client,
public static void main(String[] args) {
(2) réception de messages,
ClientTCP client = new ClientTCP("127.0.0.1",1500,"Bonjour!");
(3) fermeture de la connexion par le client
}
}
IvMad, 2002-2013 17 IvMad, 2002-2013 18
Les Sockets (connecteurs réseaux) Les Sockets (connecteurs réseaux)
while(true) { // Fermeture de la connexion par le client
// Connexion acceptée try {
SkC = SkS.accept(); SkC.close();
System.out.println("Connexion acceptée: "+SkC.getInetAddress()); System.out.println("TCP Serveur STOP!");
// Instancier le lecteur du flux d'entrée break;
input = new BufferedReader(new } catch (IOException e) {
InputStreamReader(SkC.getInputStream())); System.err.println(e); }
// Réception et affichage des messages du client }
try { } catch (IOException e) {
while(true) { System.err.println(e); }
// lecture en boucle des lignes envoyées par le client }
message = input.readLine(); // Application principale avec appel du constructeur
if (message == null) break; // Sortie de la boucle public static void main(String[] args) {
System.out.println(message); // Affiche le message client new ServeurTCP();
} }
} catch (IOException e) { }
System.err.println(e.getMessage());
}
Serveur HTTPD (1) Serveur HTTPD (2)
import java.net.*; import java.io.*; import java.util.*; if (str[0].equals("GET")) { // Vérifier si la requête démarre par "GET"
public class monoHttpd { req = str[1].substring(1); // On enlève '/' devant le nom du fichier
// Le serveur traite une seule connexion à la fois try {
public static void main(String[] argv) throws IOException { FileInputStream fis = new FileInputStream(req);
ServerSocket ss = new ServerSocket(1234); // Ouvrir le fichier demandé
// Installation du serveur sur un port byte[] data = new byte[fis.available()];
System.out.println("Serveur HTTP sur le port 1234"); // available() retourne le nombre de bytes à lire
// Message du côté du Serveur fis.read(data);
Socket sock = ss.accept(); // ça boucle en attente de requête // Lire les données du fichier dans le tableau de bytes
try { out.write(data);
// Formater la sortie // Envoyer les données au client
OutputStream out = sock.getOutputStream(); } catch ( FileNotFoundException e ) {
// Lecture de la requête new PrintStream(out).println("404 Not Found"); }
String req = (new BufferedReader(new } else { new PrintStream(out).println("400 Bad Request"); }
InputStreamReader(sock.getInputStream()))).readLine(); sock.close();
System.out.println("Requête: " + req); } catch ( IOException e ) {
// Traitement de la requête "GET /index.html HTTP/1.1" System.out.println("I/O error " + e.getMessage()); }
String str[] = req.split(" "); // Décompose 'req' par le délimiteur }
" " et charge en éléments de tableau }
IvMad, 2002-2013 23 IvMad, 2002-2013 24
Serveur HTTPD
Le côté Serveur
Partie XIV
La page 'index.html' Le fichier 'index.html' Programmation en Java par
Socket en TCP
et Threads
Threads et processus Les Threads Java
• Un thread est une portion de code capable de • Lorsqu'un programme est exécuté sur un système
s'exécuter en parallèle à d'autres traitements. multitâche, l'OS crée un processus dédié, disposant de
• Un thread n'est pas un processus. certaine ressources (mémoire, ...).
• Les threads partagent la même mémoire contrairement • Un thread est une unité d'exécution plus "petite" qu'un
aux processus. processus.
• Les threads sont utiles pour: – Les threads issus d'un même processus partagent le même
espace mémoire chacun doté d'une certaine priorité.
– faire des traitements en tâche de fond;
– Un système multiprocesseur peut exécuter les threads d'un
– exécuter plusieurs instances d'un même code pour accélérer programme simultanément, un sur chaque processeur.
le traitement;
– On utilise les threads pour améliorer la réactivité d'un
– autoriser plusieurs connexions simultanées sur un serveur système: pour traiter séparément une connexion réseau et
HTTP ou un chat; un calcul en mémoire ou pour améliorer la réactivité d'une
– les threads s'exécutent en temps partagé. interface graphique.
IvMad, 2002-2013 27 IvMad, 2002-2013 28
Cycle de vie des Threads Java Cycle de vie des Threads Java
• Un thread peut être dans un des cinq états suivants:
– création : le thread vient d'être créé, mais il n'a pas encore
été exécuté;
– exécutable : le thread est candidat à l'exécution, il attend que
le système lui alloue le processeur pendant une certaine
durée, appelée quantum de temps;
– en cours d'exécution : le thread est en cours d'exécution par
le processeur (sur un système monoprocesseur, un seul
thread peut se trouver dans cet état);
– bloqué : le thread a provoqué une opération bloquante ou
s'est "endormi" volontairement pour une certaine durée;
– détruit : le thread a fini son exécution ou a été arrêté par un
autre thread.
Manipulation des threads en Java Manipulation des threads en Java
• Un thread est un objet en Java. • Pour tester les threads on peut créer une classe gérant
1. Pour utiliser des threads dans un programme, il suffit un constructeur et un String en paramètre pour
d'hériter de la classe Thread et de redéfinir la spécifier le nom du thread.
méthode run() • La classe comprend la méthode getName() pour
– La méthode run() est automatiquement appelée au moment retourner ce nom du thread en cours.
où le thread est démarré. • La classe Thread se trouvant dans le package java.lang,
2. On peut procéder aussi par l'implémentation de alors aucune instruction import n'est nécessaire.
l'interface Runnable et instancier un objet Thread • Java utilise un ordonnanceur qui détermine l'ordre
avec l'implémentation de cette interface. d'exécution, qui s'avère souvent aléatoire.
– Lorsque l'ordonnanceur passe d'un thread à un autre, le
thread interrompu est mis en sommeil tandis que l'autre est
en éveil
IvMad, 2002-2013 31 IvMad, 2002-2013 32
Manipulation des threads en Java TCP en plusieurs clients
L'ordre d'exécution est souvent aléatoire
TCP en plusieurs clients TCP en plusieurs clients
Serveur HTTPD multithread Serveur HTTPD multithread
// méthode qui lance le thread try {
public void run() { // ouverture du fichier
try { FileInputStream fis = new FileInputStream(req);
// affiche le nom du thread lancé // coder le contenue en byte
System.out.println(this.getName()); byte[] data = new byte[fis.available()];
// flux de sortie vers le client // lecture du fichier
OutputStream out = sock.getOutputStream(); fis.read(data);
// récupère la requête // Envoi sur le réseau vers le client
String req = (new BufferedReader(new out.write(data);
InputStreamReader(sock.getInputStream()))).readLine(); } catch(FileNotFoundException e) {
System.out.println("Request: "+req); new PrintStream(out).println("404 Not Found");}
// décompose la requête } else
StringTokenizer st = new StringTokenizer( req ); new PrintStream(out).println("400 Bad Request");
if ( (st.countTokens() >= 2) && sock.close();
st.nextToken().equals("GET") ) { } catch (IOException e) {
if ( (req = st.nextToken()).startsWith("/") ) System.out.println("I/O error " + e);
req = req.substring( 1 ); }
if ( req.endsWith("/") || req.equals("") ) }
req = req + "index.html"; }