<<<M1 - UE2
2 Communication par Socket
Note : on pourra se référer à l'API JavaSE 7 pour plus de détails.
Note :
2.1. Représentation et traitement des adresses IP
La classe InetAddress permet de représenter des adresses Internet. Elle comporte deux champs :
Parmi les méthodes les plus utiles on trouve :
- byte[] getAddress()
- String getHostAddress()
- String getHostName()
- static InetAddress getByName(String host)
- static InetAddress[] getAllByName(String host)
- static InetAddress getLocalHost()
API InetAdress
Il existe également Inet4Address et Inet6Address.
2.1.1. Exemple 1 : getByName
On cherche à obtenir l'adresse IP de différents hôtes :
Warning: file_get_contents(ens/m1/info/ue2/Code1.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
Le résultat en sortie est par exemple :
yahoo.fr/87.248.120.148 # yahoo.fr
/172.20.41.8 # janus.info-ua
Error: java.net.UnknownHostException: www.xtg9yhfr.fr
2.1.2. Exemple 2 : getAllByName
On cherche à obtenir l'ensemble des adresses IP de www.yahoo.com
Warning: file_get_contents(ens/m1/info/ue2/Code2.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
Le résultat en sortie est par exemple :
www.yahoo.com/87.248.122.122 # www.yahoo.com
www.yahoo.com/87.248.112.181 # www.yahoo.com
www.yahoo.com/2a00:1288:f006:1fe:0:0:0:3000 # www.yahoo.com
www.yahoo.com/2a00:1288:f00e:1fe:0:0:0:3000 # www.yahoo.com
www.yahoo.com/2a00:1288:f00e:1fe:0:0:0:3001 # www.yahoo.com
www.yahoo.com/2a00:1288:f006:1fe:0:0:0:3001 # www.yahoo.com
2.1.3. Exemple 3 : getLocalHost
On cherche à obtenir l'adresse IP de la machine sur laquelle on opère :
Warning: file_get_contents(ens/m1/info/ue2/Code3.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
Le résultat en sortie est par exemple :
richer/172.20.41.171
2.1.4. Exemple 4 : byte[] getAddress
On cherche à obtenir l'adresse IP de la machine sur laquelle on opère :
Warning: file_get_contents(ens/m1/info/ue2/Code4.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
Le résultat en sortie est par exemple :
172.20.41.171
2.2. Gestion des URL
La classe URL permet de représenter un Unified Resource Locator, c'est à dire un lien sur une ressource internet. On utilise une classe (plutôt qu'une chaîne) afin d'identifier les différents éléments qui composent l'URL. Il existe différents constructeurs :
- URL(String spec)
- URL(String protocol, String host, int port, String file)
- URL(String protocol, String host, int port, String file, URLStreamHandler handler) : on spécifie un gestionnaire de protocole
- URL(URL context, String spec)
Les méthodes les plus utilisées sont :
- String getHost()
- String getPath()
- int getPort()
- URLConnection openConnection()
- InputStream openStream() , équivalent à openConnection().getInputStream()
2.2.1. créer une URL
Warning: file_get_contents(ens/m1/info/ue2/URLCreate.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
protocol: http
host: www.info.univ-angers.fr
port: 80
path: /membre_fiche.php
query: us_id=23
file: /membre_fiche.php?us_id=23
2.2.2. lire depuis une URL
Warning: file_get_contents(ens/m1/info/ue2/URLReader.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
2.2.3. lire une image depuis une URL
Warning: file_get_contents(ens/m1/info/ue2/URLContent.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
sun.awt.image.URLImageSource
2.2.4. ecrire vers une URL
On utilise la classe URLConnection obtenue depuis openConnection().
Warning: file_get_contents(ens/m1/info/ue2/URLWriter.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
POST: Hello Jean-Michel Richer
2.2.5. URLEncoder et URLDecoder
Les classes URLEncoder et URLDecoder ont pour but de coder et décoder les URL. Ces classes possèdent des méthodes statiques :
- static String URLEncoder.encode(String s)
- static String URLEncoder.encode(String s, String enc) avec description de l'encodage
- static String URLDecoder.decode(String s)
- static String URLDecoder.decode(String s, String enc)
2.2.6. URLConnection
Il s'agit d'une class abstraite qui permet d'ouvrir une connexion associée à une URL. Plusieurs méthodes lui sont associées.
Warning: file_get_contents(ens/m1/info/ue2/URLConnectionRetriever.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
java URLConnectionRetriever http://www.info.univ-angers.fr
Content type: text/html
Content encoding: null
Content length: 6186
Date: 1350615476000
text/html
null
null
On peut également utiliser cette classe pour envoyer des données à un formulaire :
Warning: file_get_contents(ens/m1/info/ue2/URLPostForm.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
java URLPostForm http://localhost/pub/richer/person_form.php
<html>
<head>
<title>person form</title>
</head>
<body>
<p>Hello Jean-Michel Richer</p></body>
</html>
2.3. Sockets
Un socket est une des extrémités d'un canal de communication entre deux interlocuteurs dans un dialogue de type client / serveur. On dispose donc de deux classes pour représenter le client et le serveur :
- Socket pour le client
- ServerSocket pour le serveur
2.3.1. la partie client : socket
Il s'agit de la partie la plus simple, on se connecte au serveur en spécifiant son adresse, puis on lit les messages envoyés par le serveur, ou on écrit au serveur.
Warning: file_get_contents(ens/m1/info/ue2/SocketClient.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
2.3.2. la partie serveur : ServerSocket
Le serveur ouvre un port de communication et attend qu'un client se connecte.
Warning: file_get_contents(ens/m1/info/ue2/SocketServer.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
Le serveur précédent n'est pas très intéressant car il n'accepte qu'un client, on peut mettre en place un serveur qui répond à plusieurs clients, en utilisant une boucle while :
Warning: file_get_contents(ens/m1/info/ue2/MultiSocketServer.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
Le serveur multi-client est plus intéressant mais souffre d'un défaut : les requêtes des clients sont traitées l'une après l'autre : si le traitement prend du temps, alors les autres clients doivent attendre. Pour résoudre ce problème on crée une classe qui sera un thread et qui se charge du dialogue avec le client, ainsi on peut prendre en charge rapidement un autre client.
Warning: file_get_contents(ens/m1/info/ue2/MultiThreadSocketServer.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
Warning: file_get_contents(ens/m1/info/ue2/ClientDialogThread.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
2.4. Datagrammes UDP
Les sockets vus précédemment utilisent TCP, un protocole fiable qui réexpédie les données perdues et réarrange les trames de manière à obtenir l'ordre initial de la transmission.
UDP (User Datagram Protocol) est quant à lui un protocole de transfert rapide mais non fiable.
Java implante UDP grâce à deux classes :
- DatagramSocket envoi et réception de datagrammes
- DatagramPacket représente les paquets de données à envoyer ou recevoir
Contrairement aux Sockets, c'est le paquet qui contient les informations de connexion.
2.4.1. la classe DatagramPacket
Celle-ci prend deux formes lors de la construction en fonction que l'on envoie ou reçoit les données :
- DatagramPacket(byte buffer[], int length, InetAddress ia, int port) : permet de coder les données à envoyer
- DatagramPacket(byte buffer[], int length) : permet de définir le tampon qui reçoit les données ainsi que sa longueur
2.4.2. la classe DatagramSocket
Même principe que le DatagramPacket :
- DatagramSocket() : permet de définir un socket pour l'envoi
- DatagramSocket(int port) : permet de définir un socket de réception sur le port indiqué
2.4.3. Exemple
Voici un exemple de client / serveur en UDP où le serveur renvoie le message reçu en majuscule.
2.4.3.a le client
Warning: file_get_contents(ens/m1/info/ue2/UDPClient.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
2.4.3.b le serveur
Warning: file_get_contents(ens/m1/info/ue2/UDPServer.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
2.5. Gestion de protocole avec URLStreamhandler
La gestion de protocole consiste permet l'accès et la récupération de données, ceci en fonction du protocole choisi : ftp, http, ... Quatre classes sont dévolues à ce type de traitement :
- URL
- URLConnection
- URLStreamHandler
- URLStreamHandlerFactory
(Extrait d'un white paper from developMentor)
Warning: file_get_contents(ens/m1/info/ue2/DaytimeURLConnection.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
Warning: file_get_contents(ens/m1/info/ue2/Handler.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
Warning: file_get_contents(ens/m1/info/ue2/NewFactory.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
Warning: file_get_contents(ens/m1/info/ue2/UserHandler.java): Failed to open stream: No such file or directory in
/home/jeanmichel.richer/public_html/html_business.php on line
448
Pour exécuter le programme, il faut ouvrir les ports correspondants grâce à xinetd
- installer le paquet xinetd
- modifier le fichier /etc/xinetd.d/echo :
service echo
{
disable = no
type = INTERNAL
id = echo-stream
socket_type = stream
protocol = tcp
user = nobody
wait = no
}
- modifier le fichier /etc/xinetd.d/daytime :
service daytime
{
disable = no
type = INTERNAL
id = daytime-stream
socket_type = stream
protocol = tcp
user = root
wait = no
}
- pour finger ajouter le fichier /etc/xinetd.d/finger
service finger
{
disable = no
socket_type = stream
user = nobody
wait = no
server = /usr/bin/finger
}
- relancer xinetd : sudo service xinetd restart
- on peut tester dans un premier temps grâce à telnet :
telnet localhost 13
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
18 OCT 2012 14:38:46 CEST
Connection closed by foreign host.
telnet localhost 79
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Login Name Tty Idle Login Time Office Office Phone
richer Jean-Michel Richer pts/2 2 Oct 18 09:15 (:0)
richer Jean-Michel Richer pts/4 Oct 18 14:20 (:0)
Connection closed by foreign host.
On peut ensuite tester avec le UserHandler :
java UserHandler daytime://richer