Programmation réseau en Java
La classe InetAddress - Internet adresses (numérique IP adresses et nomes de hosts )
Des exemples de protocoles des couches de transport et d'application (Image copiée de ce site )
IP (Internet protocol) - commutation par paquets(datagrames). Pas d'API Java standard permettant la manipulation directe de protocole IP
UDP (User Datagram Protocol) - la transmission par message, rapide, non fiable, en mode non connecté
TCP (Transmission Control Protocol) - transmission par flot, fiable, moins rapide en mode connecté
Paquetage java.net
Ce paquetage fournit un ensemble de classes pour communiquer sur le réseau Internet (et Intranet), télécharger des URL, définir des nouveaux protocoles
Il permet notamment de créer et d'accéder à
- des connexions URL
- des connexions Stream socket (TCP)
- des connexions Datagram socket (UDP)
Interfaces | Classes | Exceptions |
ContentHandlerFactory
FileNameMap SocketImplFactory SocketOptions URLStreamHandlerFactory |
Authenticator ContentHandler DatagramPacket DatagramSocket MulticastSocket DatagramSocketImpl InetAddress NetPermission PasswordAuthentication ServerSocket Socket SocketImpl SocketPermission URL URLClassLoader URLConnection HttpURLConnection JarURLConnection URLDecoder URLEncoder URLStreamHandler |
MalformedURLException
ProtocolException SocketException BindException ConnectException NoRouteToHostException UnknownHostException UnknownServiceException |
32 bits en IPv4:
0xxx: il s'agit d'une adresse de classe A
10xx: il s'agit d'une adresse de classe B
110xx: il s'agit d'une adresse de classe C
128 bits en IPv6
Ne possède pas des variables et constructeurs publiques
Quelques fonctions:
static InetAddress getByName(String host) -
Détermine l'adresse IP d'une machine (host).
static InetAddress[] getAllByName(String host) -
Détermine tous
les adresses IP d'une machine.
public static InetAddress getByAddress(byte[] addr) - IPv4 doit
être 4 octets, IPv6 - 16.
static InetAddress getLocalHost() - l'adresse de la machine
locale.
getByName(null) ~ getByName("localhost") ~ getByName("127.0.0.1")
String getHostAddress() - l' adresse IP comme une
chaîne "%d.%d.%d.%d".
String getHostName() - nom de la machine
à
cette adresse.
boolean isMulticastAddress() - vérifie s'il
sois
une multicast IP addresse.
import
java.net.*; public class NSLookupApp { public static void main(String args[]) { try { if(args.length!=1){ System.out.println("Usage: java NSLookupApp hostName"); return; } InetAddress host = InetAddress.getByName(args[0]); String hostName = host.getHostName(); System.out.println("Host name: "+hostName); System.out.println("IP address: "+host.getHostAddress()); } catch(UnknownHostException ex) { System.out.println("Unknown host"); return; } } } |
java
NSLookupApp
localhost Host name: localhost IP address: 127.0.0.1 |
Exercice: Affichez tous les adresses
IP
de yahoo.com
Rappel
URL: Uniforme Resource Locator.
Représente une chaîne de caractères qui permet localisation de manière unique une ressource sur le réseau Internet - le protocole à utiliser, la machine hôte(adresse IP+numero de port), le chemin d'accès(path), nom de la ressource(fichier):
protocole: //machine[:port]/chemin/nom
https://ff.tu-sofia.bg/JavaAv/network/Reseau.html
Description
Contient des méthodes pou créer et ouvrir des pages Web. Ne possède pas des variables.
Constructeurs
On peut construire un objet
URL u1 = new URL("https", "ff.tu-sofia.bg", "/futurs-etudiants/");
URL u2 = new URL("https://ff.tu-sofia.bg/");
URL u3 = new URL(u2, "Java/Network.htm"); // https://ff.tu-sofia.bg/Java/Network.html
Tous les constructeurs peuvent lever une MalformedURLException.
Les different types des objets URL sont
utilisés avec des differents protocoles, le plus souvent avec
http, https et ftp . Les URL pour ces protocoles sont utilisés
pour localiser des differents fichiers, comme pages Web , images,
fichiers multimedia, fichiers texte et les programmes
téléchargeables. On peut les utiliser aussi bien pour les
programmes executables, comme les scripts CGI.
Exemple
import
java.net.MalformedURLException; import java.net.URL; public class Test { public static void main(String[] args) throws MalformedURLException { // creates a URL with string representation. URL url1 = new URL("https://ff.tu-sofia.bg"+ "/sites/default/files/documents_ff/FICHE_INSCRIPION-IC_002.pdf"); // creates a URL with a protocol,host name,and path URL url2 = new URL("https", "ff.tu-sofia.bg", "/futurs-etudiants/"); //create a URL with another URL and path URL url3 = new URL("https://ff.tu-sofia.bg"); URL url4 = new URL(url3, "/futurs-etudiants/"); // print the String representation of the URL. System.out.println(url1.toString()); System.out.println(url2.toString()); System.out.println(); System.out.println("Different components of the URL"); // Retrieve the protocol for the URL System.out.println("Protocol url1: " + url1.getProtocol()); // Retrieve the host name of the URL System.out.println("Hostname url1: " + url1.getHost()); // Retrieve the default port System.out.println("Default port url1: " + url1.getDefaultPort()); // Retrieve the path of URL System.out.println("Path url4: " + url4.getPath()); // Retrieve the file name System.out.println("File url1: " + url1.getFile()); } } |
On peut lier des classe I/O à un URL
Exemple: copier in fichier binaire d'un URL
import java.io.*; |
Avec un tampon:
import java.io.*; |
Exemple - affichage de code source d'une page URL
import
java.io.*; import java.net.*; class ReadURL{ public static void main(String[] a){ try{ URL url = new URL("https://ff.tu-sofia.bg"); BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream())); String line; while((line=br.readLine()) !=null) { System.out.println(line); } br.close(); }catch(MalformedURLException me) { System.out.println("MalformedURLException: "+ me); }catch (IOException ioe){ System.out.println("IOException: "+ ioe); } } } |
Cette classe offre un meilleur contrôle sur le téléchargement d'information référencée par un URL
Construction - à deux pas 1) construire un URL 2)utiliser la fonction openConnection()
URL refg = new URL("https://ff.tu-sofia.bg");
URLConnection refg_c = refg.openConnection();
Avantages:
La classe dispose de méthodes permettant de connaître
pour un contenu:
son type: getContentType()
son en-tête: getHeaderField()
et d'autre information:
getContentEncoding()
getContentLength()
getDate()
getExpiration()
getLastModifed()
La classe permet d'écrire vers un URL pour fournir au serveur des données(cgi script)
Pour se faire il faut obtenir de la connexion un flot de sortie (OutputStream) (en utilisant getOutputStream() ) et donner la valeur true à la variable interne DoOutput (en utilisant setDoOutput(true)).
Exemple
socket - software abstraction pour représenter les
deux "terminaux"
de la connexion entre les deux machines.
ServerSocket - lie l'application serveur
au port correspondant, écoute le réseau
Socket - utilisé par l'application
client pour se connecter et "causer". Utilisé par l'application
serveur pour "causer" une fois la connexion établie.
procédure serveur:
Exemple 1: Client qui envoie un message SMTP
Extrait de rfc SMTP
++++++++++++++++
3.5. OPENING AND CLOSING
At the time the transmission channel is opened there is an
exchange to ensure that the hosts are communicating with the hosts
they think they are.
The following two commands are used in transmission channel
opening and closing:
HELO <SP> <domain> <CRLF>
QUIT <CRLF>
In the HELO command the host sending the command identifies
itself; the command may be interpreted as saying "Hello, I am
<domain>".
+++++++++++++++++++++++++++++++++
=====================
Example of the SMTP Procedure
This SMTP example shows mail sent by Smith at host Alpha.ARPA,
to Jones, Green, and Brown at host Beta.ARPA. Here we assume
that host Alpha contacts host Beta directly.
S: MAIL FROM:<Smith@Alpha.ARPA>
R: 250 OK
S: RCPT TO:<Jones@Beta.ARPA>
R: 250 OK
S: RCPT TO:<Green@Beta.ARPA>
R: 550 No such user here
S: RCPT TO:<Brown@Beta.ARPA>
R: 250 OK
S: DATA
R: 354 Start mail input; end with <CRLF>.<CRLF>
S: Blah blah blah...
S: ...etc. etc. etc.
S: <CRLF>.<CRLF>
R: 250 OK
The mail has now been accepted for Jones and Brown. Green did
not have a mailbox at host Beta.
======================================================
voir RFC 821 - SMTP
Example 1
import java.net.*; import java.net.*; |
et l'interface utilisateur du programme:
import java.awt.*; |
Exercice: Introduisez dans l'interface les annonces pour les problèmes possibles.
Exemple 2: Un simple serveur et client:
public class FirstServer {
// Choose a port outside of the range 1-1024:
public static final int PORT = 8080;
public static void main(String[] args)
throws IOException {
ServerSocket s = new ServerSocket(PORT);
System.out.println("Started: " + s);
try {
// Blocks until a connection occurs:
Socket socket = s.accept();
try {
System.out.println(
"Connection
accepted: "+ socket);
BufferedReader in =
new
BufferedReader(
new InputStreamReader(
socket.getInputStream()));
// Output is
automatically
flushed
// by PrintWriter:
PrintWriter out =
new
PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())),true);
while (true) {
String str
= in.readLine();
if
(str.equals("END"))
break;
System.out.println("Echoing:
" + str);
out.println(str);
}
// Always close the two sockets...
} finally {
System.out.println("closing...");
socket.close();
}
} finally {
s.close();
}
}
}
// Very simple client that just sends
// lines to the server and reads lines
// that the server sends.
import java.net.*;
import java.io.*;
public class FirstClient {
public static void main(String[] args)throws IOException
{
// Passing null to getByName() produces the
// special "Local Loopback" IP address, for
// testing on one machine w/o a network:
// Alternatively, you can use
// the address or name:
// InetAddress addr =
InetAddress.getByName("127.0.0.1");
// InetAddress addr =
InetAddress.getByName("localhost");
String serveur = null;
InetAddress addr =
InetAddress.getByName(serveur);
System.out.println("addr = " + addr);
Socket socket = new Socket(addr,
FirstServer.PORT);
// Guard everything in a try-finally to make
// sure that the socket is closed:
try {
System.out.println("socket = " +
socket);
BufferedReader in =
new BufferedReader(
new
InputStreamReader(socket.getInputStream()));
BufferedReader sin = new
BufferedReader(
new InputStreamReader(System.in));
// Output is automatically flushed
// by PrintWriter:
PrintWriter out =
new PrintWriter(
new
BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())),true);
for(int i = 0; i <10 ; i ++) {
System.out.println("input
a line [empty for finish] " + i + ":");
String s = sin.readLine();
if(s.length()==0)
break;
out.println(s +
" :" +i);
String str =
in.readLine();
System.out.println(str);
}
out.println("END");
}
finally {
System.out.println("closing...");
socket.close();
}
}
}
>java
FirstServer Started: ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=8080] Connection accepted: Socket[addr=127.0.0.1/127.0.0.1,port=1029,localport=8080] Echoing: premiere ligne :0 Echoing: deuxieme ligne :1 Echoing: troisieme ligne :2 closing... |
>java FirstClient addr = localhost/127.0.0.1 socket = Socket[addr=localhost/127.0.0.1,port=8080,localport=1033] input a line [empty for finish] 0: first line :0 input a line [empty for finish] 1: second line :1 input a line [empty for finish] 2: third line :2 input a line [empty for finish] 3: closing... |
//: MultiClientServer.java
// A server that uses multithreading to handle
// any number of clients.
import java.io.*;
import java.net.*;
class ServeOneClient extends Thread {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public ServeOneClient(Socket s) throws
IOException {
socket = s;
in = new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
// Enable auto-flush:
out = new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream()
)
),
true);
// If any of the above calls throw an
// exception, the caller is responsible for
// closing the socket. Otherwise the thread
// will close it.
start();
// Calls run()
}
public void run() {
try {
while (true) {
String str = in.readLine();
if (str.equals("END")) break;
System.out.println("Echoing: " + str);
out.println(str);
}
System.out.println("closing...");
} catch (IOException e) { }
finally {
try {
socket.close();
} catch(IOException e) {}
}
}
}
public class MultiClientServer {
static final int PORT = 8080;
public static void main(String[] args) throws IOException
{
ServerSocket s = new ServerSocket(PORT);
System.out.println("Server Started");
try {
while(true) {
// Blocks until a
connection
occurs:
Socket socket =
s.accept();
try {
new
ServeOneClient(socket);
} catch(IOException e)
{
// If it
fails, close the socket,
// otherwise
the thread will close it:
socket.close();
}
}
} finally {
s.close();
}
}
}
Clients portent noms:
// Client with name
import java.net.*;
import java.io.*;
public class ClientWithName {
public static void main(String[] args)throws IOException {
// Passing null to getByName() produces the
// special "Local Loopback" IP address, for
// testing on one machine w/o a network:
// Alternatively, you can use
// the address or name:
// InetAddress addr =
InetAddress.getByName("127.0.0.1");
// InetAddress addr =
InetAddress.getByName("localhost");
String serveur = null;
InetAddress addr = InetAddress.getByName(serveur);
System.out.println("addr = " + addr);
Socket socket = new Socket(addr, FirstServer.PORT);
// Guard everything in a try-finally to make
// sure that the socket is closed:
try {
System.out.println("socket = " + socket);
BufferedReader sin = new BufferedReader(
new InputStreamReader(System.in));
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
//
Output is automatically flushed
//
by PrintWriter:
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())),true);
System.out.print("Your name: ");
String name = sin.readLine();
for(int i = 0; i <10 ; i ++) {
System.out.println("input a line [empty for finish] :");
String s = sin.readLine();
if(s.length()==0) break;
out.println(name+":"+s);
String str = in.readLine();
System.out.println(str);
}
out.println("END");
} finally {
System.out.println("closing...");
socket.close();
}
}