Post on 23-Jul-2022
CNAM Réseaux C3 – 2005 - ©Andrey Sadovykh
Programmation par Sockets.
Sockets en Java.
Andrey SADOVYKH
sadovykh@free.fr
http://sadovykh.free.fr/cnam/
2
Plan du cours
� Principes de Sockets
� Sockets en Java
� TD - Carnet d’Adresses partagé – Sockets TCP
CNAM Réseaux C3 – 2005 - ©Andrey Sadovykh
Principes de Sockets
4
Plans
� Principes de Sockets
� Définition de sockets
� Protocoles Internet � TCP et UDP
� Format réseaux de données
� Sockets UDP
� Sockets TCP
� Problème de Blocage
5
Principes des sockets
� Socket == Fichier
write() pour envoyer read() pour recevoir
Client Server
80 HTTP
Donnes-moi la page
Index.htmlyahoo.fr
ports ports
6
Définition des sockets
� Une socket = {une famille ; un mode de communication ; un protocole}
� Exemple de familles de sockets :� processus sur la même station Unix : sockets locales (AF_UNIX en
C)� processus sur des stations différentes à travers Internet : sockets
Internet (AF_INET en C)
� Exemple de modes de communication :� Datagrames – ou mode non connecté� Flux de données – ou mode connecté� Etc.
� Exemple de protocoles de sockets : IP, UDP, TCP, …
7
Protocoles Internet
IP
AF_INET: UDP, TCP
Ethernet
TCP:
UDP:
1 2 3 4 1 2 3 4
1 2 3 4 2 1 3 4
Mode avec connexion:
Envoie par séquences
L’ordre d’envoie est respectéLa livraison est garantie
La perte de connexion est détecté
Mode sans connexion:Envoie par paquetsRéception par des plusieurs destinataires est possibleNi livraison ni l’ordre de séquence ne sont pas garantis,
même si la probabilité est 10-6
Application
8
Format Réseau –
Little / Big Endians
� short /* (2 Octets) */ long /* (8 Octets) */
� Exemple: short n=3; /* 11 en binaire*/
0…1100…0 00…00…11 0…1100…0
Motorola Intel Réseau
� Un des problèmes d’interopérabilité le plus connu.� ���� Les représentation de donnée sur chaque
d’extrémités peuvent être différentes.� En C, une conversion vers format réseau (network byte
order) est nécessaire.
host byte orderBig Endians
host byte orderLittle Endians
network byte orderBig Endians
9
Sockets UDP
� Étapes d’utilisation de sockets lors de communication client-serveur en UDP :� le serveur et le client ouvrent chacun une « socket »
� le serveur la nomme (il l’attache à un de ses ports (un port précis))
� le client ne nomme pas sa socket (elle sera attachée automatiquement à un port lors de l’émission)
� le client et le serveur dialogue : write(…) et read(…)� finalement toutes les sockets doivent être refermées
� Les deux extrémités n’établissent pas une connexion :� elles ne mettent pas en oeuvre un protocole de maintien de
connexion
� si le processus d’une extrémité meurt l’autre n’en sait rien !
10
Étapes d’utilisation de sockets mode UDP: serveur reçoit les données
read()
bind()attribution d’un port
close()
socket ()
write()
close()
socket ()
Serveur Client
Initialisation:
Dialogue:
Fermeture:
11
Sockets TCP
� Étapes d’utilisation de sockets lors de communication client-serveur en TCP :� le serveur et le client ouvrent chacun une « socket »� le serveur la nomme (il l’attache à un de ses ports (un port précis))� le client n’est pas obligé de la nommer (elle sera attachée
automatiquement à un port lors de la connexion)� le serveur écoute sa socket nommée� le serveur attend des demandes de connexion� le client connecte sa socket au serveur et à un de ses ports (précis)� le serveur détecte la demande de connexion� une nouvelle socket est ouverte automatiquement� le client et le serveur dialogue sur la nouvelle socket (read, write) � le serveur attendre de nouvelles demandes de connexions� finalement toutes les sockets doivent être refermées
12
Étapes d’utilisation de sockets mode TCP: serveur reçoit les données
read()Communication
sur la nouvelle socket
bind()
attribution d’un port
close()
socket ()
write()Communication
sur la nouvelle socket
close()
socket ()
Serveur Client
Initialisation:
Dialogue:
Fermeture:
listen()
mode d’écoute
accept() connect ()Connexion:une nouvelle socket !!!
13
Problème de blocage
read()Communication
sur la nouvelle socket
bind()
attribution d’un port
close()
socket ()
write()Communication
sur la nouvelle socket
close()
socket ()
Serveur Client
listen()
mode d’écoute
accept() connect ()Blocage:
Blocage:
14
Solution: nouveau processus
accept()
fork()
… read()send()
…
read()
send()…
while(…)
Serveur: ProcessusPrincipal:
ProcessusSecondaires: Traitement de communication
données
donnéesClient2
socket1
socket2
une nouvelle socket !!!
Client1
15
Sockets TCP non bloquant
� Étapes d’utilisation de sockets lors de communication client-serveur en TCP :� le serveur et le client ouvrent chacun une « socket »
� le serveur la nomme (il l’attache à un de ses ports (un port précis))
� le client n’est pas obligé de la nommer (elle sera attachée automatiquement à un port lors de la connexion)
� le serveur écoute sa socket nommée
� le serveur attend des demandes de connexion
� le client connecte sa socket au serveur et à un de ses ports (précis)
� le serveur détecte la demande de connexion
� une nouvelle socket est ouverte automatiquement
� le serveur crée un processus pour dialoguer avec le client� le nouveau processus continue le dialogue sur la nouvelle
socket� le serveur attende en parallèle de nouvelles demandes de
connexions� finalement toutes les sockets doivent être refermées
CNAM Réseaux C3 – 2005 - ©Andrey Sadovykh
Programmation par sockets
en Java
17
Plan
� Les prérequis:
� Flux de données Java � Sockets TCP
� Sérialisation � Préparation de données
� Optionnellement: Threads � Serveur TCP non-
bloquant (voir les support )
� Spécificités
� Sockets UDP en Java
� Sockets TCP en Java
18
Pré requis
� java.io - les entrées-sorties (pp. 72-80)� InputStream / OutputStream – flux et opérations sur les
flux de données
� BufferedInputStream/BufferedOutputStream� DataInputStream/DataOutputStream
� java.io.File – opérations sur les fichiers (pp. 81-83)� FileInputStream / FileOutputStream (voir les corrections)
� Sérialisation (pp. 97-102)� Interface java.io.Serializable (voir les corrections)� ObjectInputStream/ObjectOutputStream (voir les
corrections)
19
Spécificités
� Il existe toujours des socket UDP et TCP� Les principes sont les mêmes
� Les sockets sont des objets (bien sur!)
� Les sockets TCP doivent être associées à des «flux » (in et out)� � facilité de lecture et d’écriture
� Certaines opérations sont devenues implicites
� De nouvelles opérations sur des « flux »apparaissent
� Bibliothèque java.net.*
20
Spécificités: Initialisation
client
serveur
DatagramSocket()
DatagramSocket(port)UDP
TCPclient
serveur
Socket(ServerName, ServerPort)
ServerSocket(port)
21
Sockets UDP en Java
� class DatagramSocket : (coté client et coté serveur)� Constructeur :
� DatagramSocket() : creation d’une socket UDP, libre
� Méthodes :� close() : ferme la socket.
� receive(DatagramPacket p) : reçoit un « DatagramPacket » de cette socket.
� send(DatagramPacket p) : envoit un « DatagramPacket » sur cette socket.
� class DatagramPacket :� Constructeur :
� DatagramPacket(byte[] buf, int InetAddress address,int port) : creation d’un packet à destination d’une machine et d’un port spécifiés
� …
22
Sockets TCP en Java (client)
� class Socket : (coté client, et coté serveur en partie)� Constructeur :
� Socket(String host, int port) : creation d’une socket TCP connectée sur le port et la machine hôte spécifiés.
� Méthodes :� close() : ferme la socket.� OutputStream getOutputStream() : revoie un flux de sortie
pour cette socket.� IntputStream getIntputStream() :revoie un flux d’entrée pour
cette socket.
connect() est implicite
� class OutputStream :
� Méthodes :
� write(byte[] buffer) : écrit dans le flux.
� close() : ferme flux.
� class InputStream :
� Méthodes :
� read(byte[] buffer) : lit le flux.
� close() : ferme flux.
23
Sockets TCP en Java (serveur)
� class ServerSocket : (coté serveur)� Constructeur :
� ServerSocket(int port) : creation d’une socket TCP connectée sur le port spécifié de la machine hôte.
� Méthodes :� close() : ferme la socket.
� OutputStream getOutputStream() : revoie un flux de sortie pour cette socket.
� IntputStream getIntputStream() : revoie un flux d’entrée pour cette socket.
� Socket accept() : écoute la socket et attend une requête de connection, retourne une nouvelle socket sur laquelle écouter le nouveau client (et lui seul)
bind() est implicite
listen() est implicite
CNAM Réseaux C3 – 2005 - ©Andrey Sadovykh
Exemple – Sockets en Java
25
Développement d’une application socket – une approche
1. Définition d’un protocole d’application
� Définition d’opérations (fonctions)
� Définition de messages d’entrée et de sorti, qui sont associés aux opérations
� Définition de tailles des messages
� Définition de moyennes de distinction des messages (codes de message, port différant, …)
2. Implémentation de sérialisation/dessérialisation
des messages.
3. Déploiement des mécanismes réseaux (sockets)
26
Exemple : Server Echo TCP.
1 opération � Description : Client envoie une chaîne de caractères au Serveur.
Serveur la renvoie en y ajoutant « C’est l’écho ».
� Opérations : Echo� Message d’entrée - String echoString de
� taille variable, ce que nécessite envoie de taille actuelle avant de chaque message.� Message de sortie – String reponse = « C’est l’écho :» + echoString
� taille variable, ce que nécessite envoie de taille actuelle avant de chaque message.
� Distinction de messages : Pas nécessaire, car un seul messages d’entrée et un seul message de sortie sont possible. De plus, opération est la seule.
� Sérialisation : OutputByteStream obs = new OutputByteStream ();obs. write (echoString.getBytes());
� Dessérialisation :
InputByteStream ibs = new InputByteStream ();Ibs. read(echoString.getBytes());
27
Exemple : Implantation socket
coté Serveur� Serveur:
� ouvre port 8080ServerSocket server = new ServerSocket (8080);
� attend une connexion; Socket nouvelleSocket = server.accept();
� lit une chaîne de caractères;InputStream fluxEntree = nouvelleSocket.getInputStream();byte taille [] = new byte[1];fluxEntree.read(taille);byte buffer [] = new byte [taille[0]];fluxEntree.read(buffer);
� renvoie cette chaîne en y ajoutant « C’est l’écho ».String echo = "C'est l'echo:"+ new String (buffer);OutputStream fluxSortie = nouvelleSocket.getOutputStream();byte taille2 = (byte) echo.getBytes().length;fluxSortie.write(taille2);fluxSortie.write(echo.getBytes());
� ferme toutes les connexionsnouvelleSocket.close();server.close();
28
Exemple : Implantation socket
coté Client
� Client� Crée une connexion avec Serveur
Socket client = new Socket (« localhost »,8080);
� Envoie une chaîne de caractèresString request = "Salut!";byte taille = (byte)request.getBytes().length;OutputStream fluxSortie = client.getOutputStream();fluxSortie.write(taille);fluxSortie.write(request.getBytes());
� Reçoit une chaîne de caractèresInputStream fluxEntree = client.getInputStream();byte [] taille2 = new byte[1];fluxEntree.read(taille2);byte [] buffer = new byte [taille2[0]];fluxEntree.read(buffer);
� Ferme toutes la connexions client.close();
29
Exemple : Source Serveurimport java.io.InputStream;
import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class EchoServer {
public static void main(String[] args) {
try {// nouvelle socket sur le port 8080ServerSocket server = new ServerSocket(8080);System.out.println("Serveur est demarre...");
// accepter les demandes de connexionSocket nouvelleSocket=server.accept();// lire les donneesInputStream fluxEntree = nouvelleSocket.getInputStream();byte taille [] = new byte[1];
fluxEntree.read(taille);byte buffer [] = new byte [taille[0]];fluxEntree.read(buffer);System.out.println("Echo request:"+new String(buffer));// preparer la reponse
String echo = "C'est l'echo:"+ new String (buffer);// ecrire les donneeOutputStream fluxSortie = nouvelleSocket.getOutputStream();byte taille2 = (byte) echo.getBytes().length;fluxSortie.write(taille2);
fluxSortie.write(echo.getBytes());// fermer nouvelleSocketnouvelleSocket.close();// fermer socket principaleserver.close();
} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();
}
}}
30
Exemple : Source Clientimport java.io.InputStream;
import java.io.OutputStream;import java.net.Socket;
public class EchoClient {
public static void main(String[] args) {try {
// creer et connecter une Socket clienteSocket client = new Socket ("localhost",8080);
// ecire les donneesString request = "Salut!";byte taille = (byte)request.getBytes().length;
OutputStream fluxSortie = client.getOutputStream();
fluxSortie.write(taille);fluxSortie.write(request.getBytes());
// lireInputStream fluxEntree = client.getInputStream();byte [] taille2 = new byte[1];fluxEntree.read(taille2);byte [] buffer = new byte [taille2[0]];
fluxEntree.read(buffer);
System.out.println("Response:"+new String(buffer));
// fermer socket cliente
client.close();
} catch (Exception e) {// TODO Auto-generated catch block
e.printStackTrace();}
}}
CNAM Réseaux C3 – 2005 - ©Andrey Sadovykh
Complément : Sérialisation en
Java – Puissance de Java
32
Principe
� Java défini une interface java.io.Serializable pour rendre les objet sérialisable
� Il suffit que votre classe à sérialiser implante java.io.Serializable, car tous les types est presque toutes les classe de bibliothèques Java sont sérialisable.
� Utilisez ObjectOutputStream.writeObject(Object votreObjetSerializable) pour écrier dans le flux sortant.
� et ObjectInputStream.readObject(Object obj) pour lire le flux entrant.
� Attention Interopérabilité : Cette approche n’est que utilisable si les deux extrémités sont des Applications Java
33
Utilité pour les sockets
� !!! La transmission de la taille d’un Objet est géré automatiquement.
� Lecture:� Récupérez le flux d’entrée InputStream socketInput =mySocket.getInputStream();
� Convertissez le en un flux d’ObjetObjectInputStream myStream = new ObjectInputStream (socketInput );
� Lisez votre ObjetMyClass myObj = new MyClasse();myObj = (MyClasse) myStream.readObject();
� Voir ExempleSocket2
34
Exemple 2: Source Serveurimport java.io.InputStream;
import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;
public class EchoServer {public static void main(String[] args) {
try {// nouvelle socket sur le port 8080
ServerSocket server = new ServerSocket(8080);System.out.println("Serveur est demarre...");// accepter les demandes de connexionSocket nouvelleSocket=server.accept();// lire les donnees
InputStream is = nouvelleSocket.getInputStream();ObjectInputStream fluxEntree= new ObjectInputStream(is); String request;request=(String)fluxEntree.readObject();System.out.println("Echo request:"+request);
String echo = "C'est l'echo:"+ request;// ecrire les donneeOutputStream os = nouvelleSocket.getOutputStream();ObjectOutputStream fluxSortie = new ObjectOutputStream(os);fluxSortie.writeObject(echo);
// fermer nouvelleSocketnouvelleSocket.close();// fermer socket principaleserver.close();
} catch (Exception e) {
// TODO Auto-generated catch blocke.printStackTrace();
}
}}
35
Exemple 2: Source Clientimport java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
public class EchoClient {
public static void main(String[] args) {
try {
// creer et connecter une Socket cliente
Socket client = new Socket("localhost", 8080);
// ecire les donnees
String request = "Salut!";
OutputStream os = client.getOutputStream();
ObjectOutputStream fluxSortie = new ObjectOutputStream(os);
fluxSortie.writeObject(request);
// lire les donnes
String response;
InputStream is = client.getInputStream();
ObjectInputStream fluxEntree = new ObjectInputStream(is);
response = (String) fluxEntree.readObject();
System.out.println("Response:" + response);
// fermer socket cliente
client.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}