Documente Academic
Documente Profesional
Documente Cultură
Serveur itratif
traite squentiellement les requtes adapt aux requtes qui peuvent s'excuter rapidement souvent utilis en mode non connect (recherche de la performance)
le serveur accepte les requtes puis les "dlgue" un processus fils (traitement de plusieurs clients) adapt aux requtes qui demandent un certain traitement (le cot du traitement est suffisamment important pour que la cration du processus fils ne soit pas pnalisante) souvent utilis en mode connect
Serveur concurrent
le mode connect implique une diminution des performances par rapport au mode non connect: ceci est une contrainte pour certaines applications. le mode connect permet une implmentation asynchrone des changes, plus complexe mais plus performantes que le mode non-connect.
La communication (suite)
Une application cliente est moins complexe que son homologue serveur car:
la plupart des applications clientes sont traites comme un processus conventionnel; au contraire, un serveur ncessite des accs privilgis de connexion au middleware. la plupart des applications clientes ne ncessitent pas de protection supplmentaires, le systme dexploitation assurant les protections lmentaires suffisantes, la plupart des applications clientes ne grent pas d'interactions avec plusieurs serveurs.
Processus serveur:
Offre une connexion sur le rseau, Entre indfiniment dans un processus dattente de requtes clientes, Lorsquune requte arrive, le serveur dclenche les processus associs cette requte, puis met la ou les rponses vers le client Problme : grer plusieurs clients simultanment Les types de serveurs
serveurs itratifs: ne grent quun seul client la fois serveurs parallles : fonctionnent en mode concurrent
offrent une interface de communication sur le rseau en mode non-connect, indfiniment : rceptionnent une requte client, formulent une rponse, et renvoient le message rponse vers le client selon le protocole applicatif dfini. offrent une connexion sur le rseau en mode connect, (*) rceptionnent une connexion client, offrent une nouvelle connexion sur le rseau, rptitivement : rceptionnent une requte pour cette connexion, formulent une rponse, et renvoient le message rponse vers le client, lorsque le traitement pour ce client est termin -->(*).
offrent une interface de communication en mode nonconnect, rptitivement : rceptionnent la requte client; offrent une nouvelle interface de communication sur le rseau, et crent un processus secondaire (PR. S.) charg de traiter la requte courante. (PR. S.) : formule une rponse la requte client, et renvoie le message, (PR. S.) : lorsque le traitement est termin, libre la communication, Exit.
offrent une connexion sur le rseau en mode connect, rptitivement : rceptionnent une connexion client, offrent une nouvelle connexion sur le rseau, crent un PR. S. charg de traiter la connexion courante. (PR. S.) : rptitivement : rceptionne une requte pour cette connexion, formule une rponse, et renvoie le message rponse vers le client selon le protocole applicatif dfini, (PR. S.) : lorsque le traitement est termin (propre au protocole applicatif), libre la connexion, Exit.
serveurs itratifs en mode non-connect : services qui ncessitent trs peu de traitement par requte (pas de concurrence). Exemple: serveur TIME serveurs itratifs en mode connect : services qui ncessitent trs peu de traitement par requte mais requirent un transport fiable de type TCP. Peu utilis.
serveurs concurrents en mode non-connect : pas utilis sauf si :
temps de cration dun processus extrmement faible (dpend du systme dexploitation hte) par rapport au temps de traitement dune requte, les requtes ncessitent des accs priphriques importants (dans ce cas, la solution itrative est, en effet, inacceptable).
serveurs concurrents en mode connect : offre un transport fiable et est capable de grer plusieurs requtes de diffrents clients simultanment; implmentation:
multi instanciation de processus avec un processus primaire et des processus secondaires traitant les connexions clientes,
avec un seul processus grant les multiples connexions par lintermdiaire de requtes asynchrones et primitive dattente d'vnements multiples.
Les sockets : interface client/serveur utilise lorigine dans le monde UNIX et TCP/IP. Etendue aujourdhui du micro (Cf Winsock) au Mainframe. Fournit les primitives pour le support des communications reposant sur toute suite de protocoles; les protocoles TCP/IP sont lorigine des dveloppements. Les applications cliente et serveur ne voient les couches de communication qu travers lAPI socket (abstraction):
Les sockets
Application cliente
Protocole Applicatif
Application : serveur
API Socket
API Socket
UDP
TCP
UDP
TCP
IP
IP
Physique
Physique
Les sockets
La primitive bind: permet de spcifier le point de terminaison local (essentiellement le port TCP/UDP dans lenvironnement TCP/IP). la primitive connect:
permet un client dtablir une communication active avec un serveur, le point de terminaison distant (adresse IP + port TCP/UDP dans lenvironnement TCP/IP) est spcifi lors de cet appel.
15
la primitive listen :
la primitive accept :
permet un serveur dentrer dans un mode dcoute de communication , ds lors le serveur est connectable par un client, le processus est bloqu jusqu larrive dune communication entrante. permet un serveur de recevoir la communication entrante (client), cre un nouveau socket et retourne le descripteur associ lapplication. le serveur utilise ce descripteur pour grer la communication entrante le serveur utilise le descripteur de socket prcdent pour traiter la prochaine communication venir.
Lorsque la communication est tablie, client et serveur changent des donnes afin dobtenir (client) et transmettre (serveur) le service dsir. En mode connect, clients et serveurs utilisent read et write; en mode non-connect, ils utilisent les primitives recvfrom et sendto.
socket
bind listen accept read write close
En mode connect il y a tablissement (listen,connect, accept) puis libration (close) dune connexion entre le cleint et le serveur.
CLIENT socket
requte
sendto
sendto
rponse close
18
En mode non-connect:
le client ntablit pas de connexion avec le serveur mais met un datagramme (sendto) vers le serveur. Le serveur naccepte pas de connexion, mais attend un datagramme dun client par recvfrom qui transmet le datagramme lapplication ainsi que ladresse client.
Les sockets en mode non-connect peuvent utiliser la primitive connect pour associer un socket une destination prcise. ==> send peut tre utilise la place de la sendto, De mme, si ladresse de lmetteur dun datagramme nintresse pas un processus rcepteur, la primitive recv peut tre utilise la place de la primitive recvfrom.
if ( ( sockfd = socket (.....)) < 0 ) ; if ( bind ( sockfd, ....) < 0 ) if ( listen ( sockfd , 5) < 0 ) ; );
for ( ; ; ) { newsockfd = accept ( sockfd, .....) ; if ( newsockfd < 0) err_sys( erreur de accept) ;
err_sys(erreur de socket)
err_sys (erreur de bind) err_sys ( erreur de listen
21
La primitive getpeername
Dans le monde UNIX, la primitive gethostname permet aux processus utilisateurs daccder au nom de la machine locale. Dautre part, la primitive sethostname permet des processus privilgis de dfinir le nom de la machine locale.
La primitive getsockname
Cette primitive est utilise afin de connatre le point de terminaison du distant. Habituellement, un client connat le point de terminaison (couple port/adresse IP) puisquil se connecte ce serveur distant; cependant, un serveur qui utilise la primitive accept pour obtenir une connexion, a la possibilit dinterroger le socket afin de dterminer ladresse du distant.
Cette primitive rend le nom associ au socket qui est spcifi en paramtre.
Lorsque ces fonctions sont excutes sur des machines ayant accs un serveur de noms de domaines, elles fonctionnent elles-mmes en mode client/serveur en mettant une requte vers le serveur de nom de domaines et attendent la rponse. Lorsquelles sont utilises sur des machines qui nont pas accs un serveur de noms, elles obtiennent les informations partir dune base de donnes ( simple fichier) locale.
gethostbyname spcifie un nom de domaine et retourne un pointeur vers une structure hostent qui contient les informations propres ce nom de domaine. gethostbyaddr permet dobtenir les mmes informations partir de ladresse spcifie. getnetbyname spcifie un nom de rseau et retourne une structure netent renseignant les caractristiques du rseau. getnetbyaddr spcifie une adresse rseau et renseigne la structure netent
Dans la base de donnes des protocoles disponibles sur la machine, chaque protocole a un nom officiel, des alias officiels et un numro de protocole officiel. La fonction getprotobyname permet dobtenir des informations sur un protocole donn en spcifiant son nom; renseigne la structure protoent. La fonction getprotobynumber permet dobtenir les mmes informations en spcifiant le numro de protocole. Certains numros de ports sont rservs pour les services sexcutant au-dessus des protocoles TCP et UDP. getservbyname retourne les informations relatives un service donn en spcifiant le numro du port et le protocole utilis; renseigne la structure servent.
La fonction getservbyname
TCP/IP spcifie une reprsentation normalise pour les entiers utiliss dans les protocoles. Cette reprsentation, appele network byte order, reprsente les entiers avec le MSB en premier. Une application doit renseigner certaines informations du protocole et par consquent, doit respecter le network informations byte order; Exemple le numro de port. Pour que les applications fonctionnent correctement, elles doivent translater la reprsentation des donnes de la machine locale vers le network byte order :
htonl : host to network long : convertit une valeur sur 32 bits de la reprsentation machine vers la reprsentation rseau. htons : host to network short : convertit une valeur sur 16 bits de la reprsentation machine vers la reprsentation rseau. ntohl : network to host long : convertit une valeur sur 32 bits de la reprsentation rseau vers la reprsentation machine. ntohs : network to host short : convertit une valeur sur 16 bits de la reprsentation rseau vers la reprsentation machine.
25
La primitive getsockopt
Permet une application dobtenir les informations relatives au socket. Le systme dexploitation exploite les structures de donnes internes relatives au socket et renseigne lapplication appelante.
level optname IPPROTO_IP IP_OPTIONS IPPROTO_TCP TCP_MAXSEG TCP_NODELAY SOL_SOCKET SO_DEBUG SO_DONTROUTE SO_ERROR SO_LINGER SO_OOBINLINE SO_RCVBUF SO_SNDBUF SO_RCVTIMEO SO_SNDTIMEO SO_REUSEADDR SO_TYPE
get set
Description flag option de lentte IP donne la taille max dun segment tcp ne pas retarder lenvoi pour grouper des paquets permet des infos de debugging utilise uniquement les adresses dinterface rend le status de lerreur contrle de lenvoi des donnes aprs close concerne la rception de donnes hors bande taille du buffer de rception taille du buffer denvoi timeout de rception timeout demission autorise la rutilisabilit de ladresse locale fournit le type de socket
type de donnes int int int int int struct linger int int int int int int int
non duplication des ressources associes au service, (corps du serveur), cohrence dans la gestion des versions.
Fonctionnement
Un seul processus utilisant des oprations dentre/sortie asynchrones de manire grer les communications la fois en mode connect et en mode non-connect. Deux implmentations possibles : en mode itratif et en mode concurrent.
Serveurs multi-protocoles
29
En mode itratif le serveur ouvre un socket UDP et un socket TCP, Lorsquune requte TCP arrive, le serveur utilise accept provoquant la cration dun nouveau socket servant la communication avec le client, Lorsque la communication avec le client est termine, le serveur ferme le troisime socket et ritre son attente sur les deux sockets initiales. Si une requte UDP arrive, le serveur reoit et met des messages avec le client (il ny a pas daccept); lorsque les changes sont termins, le serveur ritre son attente sur les deux sockets initiales. En mode concurrent Cration d un nouveau processus pour toute nouvelle connexion TCP et traitement de manire itrative des requtes UDP. Automate grant les vnement asynchrones optimisation maximale des ressources machines un seul processus traite toutes les variantes protocolaires (TCP et UDP) toutes les instances de services seront galement traites par le mme processus.
Serveurs multi-protocoles
30
Problme li la multiplication des serveurs : le nombre de processus ncessaires et les ressources consommes qui sont associes. La consolidation de plusieurs services en un seul serveur amliore le fonctionnement: La forme la plus rationnelle de serveur multi-services consiste dclencher des programmes diffrents selon la requte entrante : le fonctionnement dun tel serveur en mode connect est le suivant:
le serveur ouvre un socket par service offert, le serveur attend une connexion entrante sur lensemble des sockets ouverts, lorsquune connexion arrive, le serveur cre un processus secondaire (fork sous systme UNIX), qui prend en compte la connexion, le processus secondaire excute (via exec sous systme UNIX) un programme ddi ralisant le service demand.
A p p l i c a t i o n
processus secondaire
O S
AVANTAGES
le code ralisant les services nest prsent que lorsquil est ncessaire,
la maintenance se fait sur la base du service et non du serveur : ladministrateur peut grer le serveur (modifie, archiver, ... ) par service au lieu de le grer globalement. Ce schma est retenu en standard sous UNIX Le super serveur (inetd sous BSD ou xinetd sous Linux) Cest un processus multi-services multi-protocoles Offre une interface de configuration ladministrateur fichier systmes permet lajout de nouveaux services alors quaucun processus supplmentaire nest ncessaire.
Sockets UDP
Pas de constructeurs, on passe par des mthodes statiques pour crer un objet public static InetAddress getByName(String host) throws UnknownHostException Cre un objet InetAddress identifiant une machine dont le nom est pass en paramtre L'exception est leve si le service de nom (DNS...) du systme ne trouve pas de machine du nom pass en paramtre sur le rseau Si prcise une adresse IP sous forme de chane (''192.12.23.24'') au lieu de son nom, le service de nom n'est pas utilis
Une autre mthode permet de prciser l'adresse IP sous forme d'un tableau de 4 octets
Classe InetAddress
Mthodes (suite)
public static InetAddress getLocalHost() throws UnknownHostException Retourne l'adresse IP de la machine sur laquelle tourne
le programme, c'est--dire l'adresse IP locale
public String getHostName() Retourne le nom de la machine dont l'adresse est code
par l'objet InetAddress
Classe DatagramPacket
Ne pas prciser une taille plus grande que celle du tableau En gnral, length = taille de buf
Classe DatagramPacket
Constructeurs (suite)
public DatagramPacket(byte[] buf, int length, InetAddress address, int port) Cration d'un paquet pour envoyer des donnes (sous
forme d'un tableau d'octets) buf : contient les donnes envoyer length : longueur des donnes envoyer
Classe DatagramPacket
Mthodes get
InetAddress getAddress() Si paquet envoyer : adresse de la machine destinataire Si paquet reu : adresse de la machine qui a envoy le
paquet
distante Si paquet reu : port utilis par le programme distant pour envoyer le paquet
byte[] getData Donnes contenues dans le paquet int getLength() Si paquet envoyer : longueur des donnes envoyer Si paquet reu : longueur des donnes reues
Classe DatagramPacket
Mthodes set
void setAddress(InetAdress adr) Positionne l'adresse IP de la machine destinataire du
paquet
void setData(byte[] data) Positionne les donnes envoyer int setLength(int length) Positionne la longueur des donnes envoyer
Java n'impose aucune limite en taille pour les tableaux d'octets circulant dans les paquets UDP, mais
Un datagramme UDP est rarement envoy via plusieurs
datagrammes IP
Pour tenir dans un seul datagramme IP, le datagramme UDP ne doit pas contenir plus de 65467 octets de donnes Mais en pratique : il est conseill de ne pas dpasser 8176 octets
Car la plupart des systmes limitent 8 Ko la taille des
datagrammes UDP
Si tableau d'octets en rception est plus petit que les donnes envoyes
Les donnes reues sont gnralement tronques
Pour tre certain de ne pas perdre de donnes : 512 octets max Si datagramme UDP trop grand : les donnes sont tronques
Classe DatagramSocket
Socket en mode datagramme Constructeurs
public DatagramSocket() throws SocketException Cre une nouvelle socket en la liant un port
quelconque libre Exception leve en cas de problme (a priori il doit pas y en avoir)
public DatagramSocket(int port) throws SocketException Cre une nouvelle socket en la liant au port local prcis
par le paramtre port Exception leve en cas de problme : notamment quand le port est dj occup
Classe DatagramSocket
public void send(DatagramPacket p) throws IOException Envoie le paquet pass en paramtre. Le destinataire est public void receive(DatagramPacket p) throws IOException Reoit un paquet de donnes Bloquant tant qu'un paquet n'est pas reu Quand paquet arrive, les attributs de p sont modifis
identifi par le couple @IP/port prcis dans le paquet Exception leve en cas de problme d'entre/sortie
Les donnes reues sont copies dans le tableau pass en paramtre lors de la cration de p et sa longueur est positionne avec la taille des donnes reues Les attributs d'@IP et de port de p contiennent l'@IP et le port de la socket distante qui a mis le paquet
Classe DatagramSocket
Autres mthodes
public void close() Ferme la socket et libre le port laquelle elle tait lie public int getLocalPort() Retourne le port local sur lequel est lie la socket
Classe DatagramSocket
Mthode bloquante sans contrainte de temps : peut rester en attente indfiniment si aucun paquet n'est jamais reu
public void setSoTimeout(int timeout) throws SocketException L'appel de la mthode receive sera bloquante pendant au plus timeout millisecondes Une mthode receive se terminera alors de 2 faons Elle retourne normalement si un paquet est reu en moins
du temps positionn par l'appel de setSoTimeout L'exception SocketTimeoutException est leve pour indiquer que le dlai s'est coul avant qu'un paquet ne soit reu
InetAddress adr; DatagramPacket packet; DatagramSocket socket; // adr contient l'@IP de la partie serveur adr = InetAddress.getByName("scinfr222"); // donnes envoyer : chane de caractres byte[] data = (new String("youpi")).getBytes(); // cration du paquet avec les donnes et en prcisant l'adresse du serveur // (@IP et port sur lequel il coute : 7777) packet = new DatagramPacket(data, data.length, adr, 7777); // cration d'une socket, sans la lier un port particulier socket = new DatagramSocket(); // envoi du paquet via la socket socket.send(packet);
DatagramSocket socket; DatagramPacket packet; // cration d'une socket lie au port 7777 DatagramSocket socket = new DatagramSocket(7777); // tableau de 15 octets qui contiendra les donnes reues byte[] data = new byte[15]; // cration d'un paquet en utilisant le tableau d'octets packet = new DatagramPacket(data, data.length); // attente de la rception d'un paquet. Le paquet reu est plac dans // packet et ses donnes dans data. socket.receive(packet); // rcupration et affichage des donnes (une chane de caractres) String chaine = new String(packet.getData(), 0, packet.getLength()); System.out.println(" recu : "+chaine);
La communication se fait souvent dans les 2 sens Le serveur doit donc connatre la localisation du client Elle est prcise dans le paquet qu'il reoit du client Rponse au client, cot serveur System.out.println(" ca vient de : "+packet.getAddress()+":"+ packet.getPort()); // on met une nouvelle donne dans le paquet // (qui contient donc le couple @IP/port de la socket cot client) packet.setData((new String("bien recu")).getBytes()); // on envoie le paquet au client socket.send(packet);
Rception rponse du serveur, cot client // attente paquet envoy sur la socket du client socket.receive(packet); // rcupration et affichage de la donne contenue dans le paquet String chaine = new String(packet.getData(), 0, packet.getLength()); System.out.println(" recu du serveur : "+chaine);
Avantages
Simple programmer (et apprhender)
Inconvnients
Pas fiable Ne permet d'envoyer que des tableaux de byte
Un objet quelconque en byte[] pour l'envoyer Un byte[] en un objet d'un certain type aprs rception
Crer les mthodes qui font cela : lourd et dommage de faire des tches de si bas-niveau avec un langage volu comme Java Utiliser les flux Java pour conversion automatique (voir suite)
Sockets TCP
Socket : socket mode connect ServerSocket : socket d'attente de connexion du cot server
Classe Socket
Socket mode connect Constructeurs
public Socket(InetAddress address, int port) throws IOException Cre une socket locale et la connecte un port distant
public Socket(String address, int port) throws IOException,UnknownHostException Idem mais avec nom de la machine au lieu de son adresse
IP code Lve l'exception UnknownHostException si le service de nom ne parvient pas identifier la machine
Variante de ces 2 constructeurs pour prciser en plus un port local sur lequel sera lie la socket cre
Classe Socket
Contrairement aux sockets UDP, les sockets TCP n'offre pas directement de services pour mettre/recevoir des donnes On rcupre les flux d'entre/sorties associs la socket OutputStream getOutputStream()
InputStream getInputStream()
Classe Socket
Mthodes get
int getPort() Renvoie le port distant avec lequel est connect la socket InetAddress getAddress() Renvoie l'adresse IP de la machine distante int getLocalPort() Renvoie le port local sur lequel est lie la socket
Positionne l'attente maximale en rception de donnes sur le flux d'entre de la socket Si temps dpass lors d'une lecture : exception
SocketTimeoutException est leve Par dfaut : temps infini en lecture sur le flux
Classe ServerSocket
Mthodes
Attente de connexion d'un client distant Quand connexion est faite, retourne une socket permettant de
communiquer avec le client : socket de service accept
Cot client
// adresse IP du serveur InetAddress adr = InetAddress.getByName("scinfr222"); // ouverture de connexion avec le serveur sur le port 7777 Socket socket = new Socket(adr, 7777);
Cot client (suite) // construction de flux objets partir des flux de la socket ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
// criture d'une chane dans le flux de sortie : c'est--dire envoi de // donnes au serveur output.writeObject(new String("youpi")); // attente de rception de donnes venant du serveur (avec le readObject) // on sait qu'on attend une chane, on peut donc faire un cast directement String chaine = (String)input.readObject(); System.out.println(" recu du serveur : "+chaine);
// serveur positionne sa socket d'coute sur le port local 7777 ServerSocket serverSocket = new ServerSocket(7777); // se met en attente de connexion de la part d'un client distant Socket socket = serverSocket.accept(); // connexion accepte : rcupre les flux objets pour communiquer // avec le client qui vient de se connecter ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream()); ObjectInputStream input = new ObjectInputStream(socket.getInputStream()); // attente les donnes venant du client String chaine = (String)input.readObject(); System.out.println(" recu : "+chaine);
// affiche les coordonnes du client qui vient de se connecter System.out.println(" ca vient de : " +socket.getInetAddress()+":"+socket.getPort()); // envoi d'une rponse au client output.writeObject(new String("bien recu"));
Souvent utile de vrifier le type de l'objet reu Utilise instanceof Exemple
String chaine; Personne pers; Object obj = input.readObject(); if (obj instanceof String) chaine = (String)obj; if (obj instanceof Personne) pers = (Personne)obj;
Inconvnients
Plus difficile de grer plusieurs clients en mme temps Ncessite du paralllisme avec des threads (voir suite
cours) Mais oblige une bonne structuration cot serveur
Sockets TCP
Multicast IP
On a vu comment faire communiquer des applications 1 1 via des sockets UDP ou TCP UDP offre un autre mode de communication : multicast Broadcast, multicast
Plusieurs rcepteurs pour une seule mission d'un paquet Broadcast (diffusion) : envoi de donnes tous les lments d'un rseau Multicast : envoie de donnes un sous-groupe de tous les lments d'un rseau Envoi d'un datagramme sur une adresse IP particulire Plusieurs lments lisent cette adresse IP
Multicast IP
Multicast
Adresse IP multicast
Classe d'adresse IP entre 224.0.0.0 et 239.255.255.255
Classe D Adresses entre 225.0.0.0 et 238.255.255.255 sont utilisables par un programme quelconque Les autres sont rserves
Une adresse IP multicast n'identifie pas une machine sur un rseau mais un groupe multicast Avant envoi de paquet : on doit rejoindre un groupe
Identifi par un couple : @IP multicast/numro port
Un paquet envoy par un membre du groupe est reu par tous les membres de ce groupe
Multicast
Evite d'avoir crer X connexions et/ou d'envoyer X fois la mme donne X machines diffrentes En pratique
Utilis pour diffuser des informations Diffusion de flux vidos plusieurs rcepteurs Chaine de tlvision, diffusion d'une confrence Le mme flux est envoy tous au mme moment Pour rcuprer des informations sur le rseau 224.0.0.12 : pour localiser un serveur DHCP
Multicast
Classe java.net.MulticastSocket
Spcialisation de DatagramSocket Constructeurs : identiques ceux de DatagramSocket
public DatagramSocket() throws SocketException Cre une nouvelle socket en la liant un port quelconque
libre Exception leve en cas de problme (a priori il doit pas y en avoir)
public DatagramSocket(int port) throws SocketException Cre une nouvelle socket en la liant au port prcis par le
paramtre port : c'est le port qui identifie le groupe de multicast Exception leve en cas de problme
public void leaveGroup(InetAddress mcastaddr) throws IOException Quitte un groupe de multicast L'exception est leve si l'adresse IP n'est pas une
adresse IP multicast valide Pas d'exception leve ou de problme quand on quitte un groupe auquel on appartient pas
// attend un paquet en rponse socket.receive(packet); // traite le rsultat ... // quitte le groupe socket.leaveGroup(group);
Notes Il est possible que le receive rcupre le paquet que le send vient juste d'envoyer Besoin d'un autre receive pour rponse venant d'un autre lment
Concurrence
Une socket d'coute sert attendre les connexions des clients A la connexion d'un client, une socket de service est initialise pour communiquer avec ce client
UDP : se met en attente d'un paquet et regarde de qui il vient TCP : doit se mettre en attente de donnes sur toutes les sockets actives
Sockets TCP
Si ne sait pas quel est l'ordonnancement des arrives des donnes des clients ou de leur connexion au serveur Impossible grer
Sockets TCP
Sockets TCP
Java offre nativement un mcanisme permettant de grer des flux d'excution parallle
Les threads
Le processus est cr comme une copie d'un processus existant Le thread s'excute au sein d'un processus existant
Nouveau flux d'excution interne Partage des donnes du processus
Deux processus distincts avec leur mmoire propre
Threads en Java
Classe CalculFactoriel calcule un factoriel et affiche le rsultat l'cran Via un thread part public class CalculFactoriel extends Thread { protected int nb; public void run(){ int res = 1; for (int i=1; i<=nb; i++) res = res * i; System.out.println(''factoriel de ''+nb+''=''+res); } public CalculFactoriel(int nb) { this.nb = nb; } }
On instantie normalement la classe CalculFactoriel On appelle la mthode start() sur l'objet cr La squence d'instructions de la mthode run() de la classe CalculFactoriel est excute via un nouveau
thread cr
Mme exemple mais sans spcialiser la classe Thread Implmentation de l'interface Runnable
public class CalculFactoriel implements Runnable { protected int nb; public void run(){ int res = 1; for (int i=1; i<=nb; i++) res = res * i; System.out.println(''factoriel de ''+nb+''=''+res); } public CalculFactoriel(int nb) { this.nb = nb; } }
On lance un Thread gnrique qui excutera la mthode run() de l'objet de type Runnable pass en paramtre du constructeur
Les rsultats des calculs sont affichs dans l'ordre de leur lancement
Pourtant les calculs de petites valeurs sont normalement plus courts car moins de passages dans la boucle ...
Dpendance thread/processus
Un thread est cr par et dans un processus Selon le systme d'exploitation, l'ordonnancement se fait
Uniquement au niveau processus Le systme s'occupe de grer uniquement le paralllisme
des processus Un processus gre en interne l'ordonnancement de ses propres threads ordonnancs par le systme
Au niveau de tous les thread et processus Les threads des processus et les processus sont Approche mixte L'ordonnancement se fait au niveau processus mais
certains threads particuliers peuvent tre ordonnancs par le systme au mme niveau que les processus
Deux types d'ordonnancement par le systme (ou par le processus pour ordonnancer ses threads)
Premptif
Le systme interrompt l'excution des processus/threads pour partager l'accs au processeur Le systme dcide quel est le prochain processus/thread qui continuera son excution
Coopratif
Un processus/thread ne libre le processeur que Quand il est bloqu momentanment (entre/sortie ...) De sa propre initiative Le systme dcide alors quel est le prochain processus/thread qui continuera son excution
Particularit de Java
Les threads crs par le programme Les threads grant l'interface graphique Garbage collector ...
Langage multi-plateformes (windows, linux, solaris, ...) L'ordonnancement des processus/threads dpend du systme d'exploitation
Principe fondamental
On ne doit pas se baser sur un modle d'ordonnancement particulier pour dvelopper une application multi-threade en Java
Si un thread de plus haute priorit que le thread courant actif veut la main, il la rcupre alors de suite Toujours via un ordonnancement premptif
MAX_PRIORITY : niveau de priorit maximal possible (10) MIN_PRIORITY : niveau de priorit minimal possible (1) NORM_PRIORITY : niveau de priorit par dfaut (5)
Une fois que la mthode run() d'un thread est commence, on doit donc supposer que ce thread garde au pire le processeur jusqu' la fin de sa mthode run() Pour avoir un meilleur paralllisme, il faut qu'un thread passe la main un autre thread de temps en temps Dans la classe java.lang.Thread
public static void yield() Le thread s'interrompt et passe la main un autre thread for (int i=1; i<=nb; i++) { res = res * i; Thread.yield(); }
Modification de l'exemple Ajout d'un yield() aprs chaque calcul dans run()
Bien que lancs en dernier, les calculs les plus courts se terminent en premier
Ordonnancement plus naturel que le prcdent Mais aurait pu avoir un ordre moins parfait
1, 2, 4, 3, 5, 7, 6, 8, 9, 10 par exemple Correspond ce que l'on aurait avec un parralllisme physique complet
Un thread passe la main un autre ds qu'il est bloqu ou en attente, c'est--dire dans les cas suivants
Il est bloqu en attente sur une entre/sortie (flux) Il est bloqu sur l'accs un objet synchronis Il se met en attente avec un wait() Il fait une pause pendant une certaine dure avec un sleep() Il a execut un yield() pour cder explicitement la main Il se met en attente de la terminaison d'un autre thread avec un join() Il se termine Un thread de plus haute priorit demande la main
Le main() et tous les run() de tous les threads crs sont termins
Un thread peut lancer un autre thread Un thread peut attendre qu'un ou plusieurs threads se terminent Un thread peut se bloquer et attendre d'tre rveill par un autre thread
Les threads s'excutent dans la mme machine virtuelle, dans le mme espace mmoire Accs possible aux mmes objets Modification de l'exemple prcdent pour ne plus afficher les rsultats mais les stocker dans un tableau auquel tous les threads ont accs
public class CalculFactorial { protected int[] tab; protected int nb; public void run(){ int res = 1; for (int i=1; i<=nb; i++) res = res * i; //enregistre le rsultat dans tableau tab[nb - 1] = res; }
Avant d'afficher les rsultats : doit attendre que tous les threads soient termins
Un thread peut attendre qu'un thread se termine via la mthode join() appelle sur le thread dont on attend la fin
Pour l'exemple, le thread principal doit attendre que tous les threads lancs soient termins
int[] resultats = new int[10]; CalculFactoriel[] tabCF = new CalculFactoriel[10]; CalculFactoriel cf; // lance les threads for (int i=10; i>=1; i--) { cf = new CalculFactoriel(i, resultats); tabCF[i-1] = cf; cf.start(); } // attend la fin de chaque thread for (int i=0; i < 10; i++) { try { tabCF[i].join(); } catch(InterruptedException e) {System.err.println(e);} }
Une fois la boucle avec les join() passe, on est certain que tous les threads de calcul sont finis
for (int i=1; i<=10; i++) System.out.println(" factoriel de +i+"="+resultats[i-1]);
Chaque thread crit dans sa case du tableau Pas de risque de conflit dans ce cas
Problme
Si pendant l'excution de calculPuissance(), un autre thread appelle setPuissance(), le calcul sera faux ! Exemple avec un autre thread appelant setPuissance() avec la valeur 4 pendant l'excution de calculPuissance() puissance 3 de 2 = 16 Valeur 16 renvoye au lieu de 8 ...
Car l'attribut puissance est pass la valeur 4 au milieu de la boucle
Primitive synchronized
Elle s'applique sur un objet (n'importe lequel) Exclusion mutuelle sur une squence de code
Il est impossible que 2 threads excutent en mme temps une section de code marque synchronized pour un mme objet Sauf si un thread demande explicitement se bloquer avec un wait()
Sur la mthode d'une classe (s'applique tout son code pour un objet de cette classe)
public synchronized int calculPuissance(int val)
Suppression de l'erreur potentielle de calcul On rajoute synchronized dans la dfinition des mthodes
Il est alors impossible qu'un thread modifie la valeur de puissance lorsqu'un calcul est en cours
public synchronized int calculPuissance(int val) { int res = val; for (int i=1; i<puissance; i++) res = res * val; return res; } public synchronized setPuissance(int p) { puissance = p; }
Car synchronized interdit que setPuissance() soit excute tant que l'excution d'un calculPuissance() n'est pas finie
Calcul effectu correctement cette fois mais ce n'est pas celui qui tait voulu par le thread !
Exemple du calcul de puissance (suite) Pour viter ce problme, il faut protger la squence de positionnement de la puissance puis du calcul
CalculPuissance cp = new CalculPuissance(); int resultat; ... // passage de la rfrence de cp d'autres threads synchronized(cp) { cp.setPuissance(3); resultat = cp.calculPuissance(2); } System.out.println(" puissance 3 de 2 = "+resultat);
Avec ce code, il est impossible qu'un autre thread excute sur l'objet cp la mthode setPuissance() entre le setPuissance() et le calculPuissance()
Avec ce nouveau code, il y a trois sections de code protges sur l'objet cp, avec un accs en excution en exclusion mutuelle
Si un thread est en train d'excuter une de ces 3 sections protges sur l'objet cp
Note
Aucun autre thread ne peut excuter une des 3 sections protges tant que le premier thread n'a pas fini d'excuter sa section protge
La squence de code inclue dans le synchronized(cp) {...} ne contient que des rfrences cp mais ce n'est pas une obligation