TP programmation Internet en JAVA

publicité
TP programmation Internet en JAVA
préparé par P. Bakowski
Ce TP nécessite quelques préparations du logiciel. Vous pouvez utiliser l’environnement NetBeans avec le
pack SDK Java SE
Le site polytech2go.fr est accessible de l’extérieur - (http://www.polytech2go.fr/mmm.htm ou
http://www.polytech2go.fr/fff.htm ou http://www.polytech2go.fr/eee.htm)
Création et lecture dans un URL
Dans ce TP nous étudions le concept de URL et nous développons un simple programme (application
JAVA2) permettant de:
ouvrir un URL sans et avec détection d’erreur (e.g. http://www.polytech2go.fr/index.htm)
// sans détéction
URL monUrl = new URL("http","cache",3128,"http://www.polytech2go.fr/index.htm");
Attention: le serveur externe est accessible via le serveur cache de l’établissement
// avec détéction
try {
URL monUrl = new URL(. . .)
} catch (MalformedURLException e) {
// exception handler code here }
analyser un URL
System.out.println("protocol = " + aURL.getProtocol());
System.out.println("host = " + aURL.getHost());
System.out.println("filename = " + aURL.getFile());
System.out.println("port = " + aURL.getPort());
System.out.println("ref = " + aURL.getRef());
lire directement le contenu d’un URL ouvert dans l’application (code HTML)
BufferedReader in = new BufferedReader(
new InputStreamReader(monUrl.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
// sortie standard
ouvrir une connexion URL (TCP)
try {
URL monUrl = new URL("http","cache",3128,"http://www.polytech2go.fr/index.htm");
URLConnection monUrlConnection = monUrl.openConnection();
}catch (MalformedURLException e) {
// new URL() failed
. . .
}catch (IOException e) {
// openConnection() failed
. . .
}
lire dans une connexion
BufferedReader in = new BufferedReader(
new InputStreamReader(
ir.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
envoyer arguments dans une connexion
Dans le cas d’exécution d’un programme script PHP il est important de pouvoir lui fournir
les arguments et/ou les données et de lire la réponse généré par le script.
import java.net.*;
import java.util.*;
import java.io.*;
public class URLConnectionEx {
public static void main (String args[]) throws IOException {
if (args.length != 1)
throw new RuntimeException ("Syntax: java URLConnectionEg <url>");
String stringtosend = URLEncoder.encode(args[0]);
URL url = new URL ("http://www.polytech2go.fr/cgi-bin/montest.php");
URLConnection c = url.openConnection();
c.setDoOutput (true);
PrintWriter out = new PrintWriter(c.getOutputStream());
out.println("monstring=" + stringtosend); // envoi
out.close();
// lecture
}
}
Un programme serveur client en mode connecté (sockets et
TCP)
Dans ce TP nous étudions le concept de socket exprimé en langage Java et nous développons une
application simple type client-serveur.
Socket client - programme client.
Dans le programme ci-dessous nous créons un socket client (new Socket(“oak”,7)) qui se connecte au
serveur “echo” (service 7) d’une machine UNIX/LINUX en mode serveur accessible sur le réseau.
echoSocket = new Socket("serveur", 7);
// ou adresse IP
out = new PrintWriter(echoSocket.getOutputStream(),true);
in = new BufferedReader(new InputStreamReader(
echoSocket.getInputStream()));
La connexion est ensuite utilisée pour l’envoi et la lecture de la réponse sur le serveur.
Ces opérations sont effectuées sur les flots in et out.
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in));
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
System.out.println("echo: " + in.readLine());
}
Socket serveur - programme serveur.
Le serveur utilise un socket pré-définie comme ServerSocket. Le ServerSocket attend une connexion,
demandée par le client, sur la méthode accept().
try {
serverSocket = new ServerSocket(8888);
} catch (IOException e) {
System.out.println("Could not listen on port: 8888");
System.exit(-1);}
et
Socket clientSocket = null;
try {
clientSocket = serverSocket.accept();
// clientSocket parameters
} catch (IOException e) {
System.out.println("Accept failed: 4444");
System.exit(-1);}
Une fois la connexion est accepté, le serveur peut lire les données envoyées par le client
et répondre avec se propres données. Ces opérations nécessitent ouverture des flots
d’entrée et de sortie.
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(
clientSocket.getInputStream()));
La classe MonApplication contient une fonction du service écrite par utilisateur. Elle peut réaliser
l’opération écho ou une autre opération beaucoup plus complexe, par exemple, la fonction du serveur de
fichiers.
Le code ci-dessous permet d’instancier la classe MonApplication et d’effectuer le dialogue entrée-sortie
avec
String inputLine, outputLine;
// initiate conversation with client
MonApplication monap = new MonApplication(); //
outputLine = monap.fonctionService(null);
out.println(outputLine);
while ((inputLine = in.readLine()) != null) {
outputLine = monap.fonctionService(inputLine);
out.println(outputLine);
if outputLine.equals("Bye.")) break;
}
A la fin d’exécution du service les flots et les sockets ouverts dans l’application doivent être
fermés.
out.close();
in.close();
clientSocket.close();
serverSocket.close();
Sujets à développer dans ce TP:
le premier est un service “écho”
le deuxième est un service de lecture d’un fichier à distance
(voir la méthode getData())
// getData() - une méthode de lecture dans un fichier
import java.io.*;
void getData(){
char[] donnees = null;
int taille = 0;
try{
try{
fichierTexte = new File("texte.txt");
in = new FileReader(fichierTexte);
int clav = 0;
taille = (int)fichierTexte.length();
donnees = new char[taille];
clav=+ in.read(donnees,clav,taille);
}
catch(IndexOutOfBoundsException e) {}
}
catch(IOException e){
System.out.println("impossible de charger le fichier");
}
}
Communication par datagrammes UDP
Dans ce TP nous étudions le fonctionnement du mode sans connexion réalisé par le datagrammes. Le
programme client prépare et envoie un datagramme, puis il reçoit le datagramme de réponse envoyé par le
serveur. Le serveur reçoit le datagramme client, puis il exécute la fonction du service et envoie la reponse
Programme client
Le client doit déclarer plusieurs éléments:
int port;
InetAddress address;
DatagramSocket socket = null;
DatagramPacket packet;
byte[] sendBuf = new byte[256];
Il doit déclarer un socket datagramme:
DatagramSocket socket = new DatagramSocket();
Et préparer le datagramme
byte[] buf = new byte[256];
InetAddress address = InetAddress.getByName(args[0]);
DatagramPacket packet = new DatagramPacket(buf, buf.length, address,8889);
Puis l’envoyer:
socket.send(packet);
La réponse du serveur est reçu dans un tampon:
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String received = new String(packet.getData());
System.out.println("Quote of the Moment: " + received);
socket.close();
Le programme serveur
Le programme serveur est un peu plus compliqué que celui du client; il sera développé sur la base d’un
thread.
import java.io.*;
public class MonServer {
public static void main(String[] args) throws IOException {
new MonServerThread().start(); }
}
La classe MonServer fait appel à la classe MonServerThread
public class MonServerThread extends Thread {
protected DatagramSocket socket = null;
protected BufferedReader in = null;
protected boolean encore = true;
public MonServerThread() throws IOException {
super(name);
socket = new DatagramSocket(8889);
}
Après la création du thread et l’initialisation du socket type datagramme on évoque la fonction run().
Dans le run() on trouve la fonction du service fonctionService; par défaut le serveur renvoie la date
du jour (Date().toString();)
public void run() {
while (encore) {
try {
byte[] buf = new byte[256];
DatagramPacket packet= new DatagramPacket(buf, buf.length);
socket.receive(packet);
String dString = null;
if (in == null) dString = new Date().toString(); //
dString = fonctionService();
else
par défaut
// fonction du service
buf = dString.getBytes();
InetAddress address = packet.getAddress();
int port = packet.getPort();
packet = new DatagramPacket(buf,buf.length,address, port);
socket.send(packet);
} catch (IOException e) {
e.printStackTrace();
encore = false;
}
}
socket.close();
}
Sujet du TP
Développer une application client-serveur (socket type datagramme), où le serveur
effectue une addition sur deux valeurs envoyées par le client; ensuite il renvoie le
résultat au client. Solution avec un thread.
Diffusion de datagrammes (multicasting)
Dans cette étude il faut comprendre le mode de multicasting puis développer une application basée sur ce
mode de communication. (Erreur ! Source du renvoi introuvable.lire le chapitre 13 du polycopié)
Le client
Le client contient un socket type multicast. Ce socket est initialisé avec une adresse de multicast (e.g.
“230.0.0.1” - l’adresse de classe D). Ensuite il doit rejoindre le groupe de multicast pour être visible sur le
réseau.
import java.io.*;
import java.net.*;
import java.util.*;
public class MulticastClient {
public static void main(String[] args) throws IOException {
MulticastSocket socket = new MulticastSocket(8890);
InetAddress address = InetAddress.getByName("230.0.0.1");
socket.joinGroup(address);
DatagramPacket packet;
for (int i = 0; i < 5; i++) {
byte[] buf = new byte[256];
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
String received = new String(packet.getData());
System.out.println("La date: " + received);
}
socket.leaveGroup(address);
socket.close();
}
}
Le serveur
Le programme serveur diffuse en mode multicast la date actuelle enregistrée sur son ordinateur.
Ci dessous la création d’un thread MulticastServerThread
import java.io.*;
public class MulticastServer {
public static void main(String[] args) throws IOException
{
new MulticastServerThread().start();
}
}
Le MulticastServerThread est une extension du serveur MonServerThread présenté dans le TP
précédent.
import java.io.*;
import java.net.*;
import java.util.*;
public class MulticastServerThread extends Thread {
private long FIVE_SECONDS = 5000;
public MulticastServerThread() throws IOException {
super("MulticastServerThread"); }
Dans la fonction run() le serveur envoie toutes les 5 secondes la date actuelle saisie sur son ordinateur:
public void run() {
while (encore) {
try {
byte[] buf new byte[256];
String dString = null;
dString = new Date().toString();
buf = dString.getBytes();
InetAddress group = InetAddress.getByName("230.0.0.1");
DatagramPacket packet;
packet = new DatagramPacket(buf, buf.length,group, 8890);
socket.send(packet);
try {
sleep(FIVE_SECONDS);
} catch (InterruptedException e) { }
} catch (IOException e) {
e.printStackTrace();
encore = false;
}
}
socket.close();
}
Sujet du TP
1. La mise en oeuvre de l’application ci-dessus; serveur-diffuseur de la date.
2. Dans la deuxième version du programme serveur, il faut saisir un message à
diffuser:
BufferReader br = new BufferedReader(new InputStreamReader(System.in));
String message;
message = br.readLine();
3. Dans la troisième version du programme serveur, il faut diffuser un texte préparé
dans un fichier local (pour la lecture d’un fichier voir le TP2).
Téléchargement