Você está na página 1de 19

Programmation Rseau en Java

Support Numro 1 Sockets

1.

Introduction

Le langage Java a t conu par SUN, une socit dont lactivit est fortement tourne vers le rseau et qui a mis au point plusieurs protocoles rseaux utiliss sur Internet (RPC, NFS, NIS). Il peut donc paratre logique que ce langage soit tourn vers le rseau et notamment vers Internet. Courte bibliographie : Ces TPs sont bass sur les sources suivantes : - Le livre "Programmation rseau avec Java" d'Elliotte Rusty Harold paru chez O'Reilly. - Le cours de Java accessible l'URL suivante : http://www.eteks.com/coursjava/ - Des articles parus dans les revues : "Linux France Magazine" et "Login:"

2.

Historique

UNIX est un systme multi-tches et multi-utilisateurs. Les processus peuvent cooprer entre eux. Diffrents outils de communication inter-processus ont t dvelopps: les IPC (Inter Process Communication). La communication interprocess peut se faire travers les signaux et les pipes. Mais tandis que la version d'ATT tait oriente gestion de ressources (smaphores, messages, mmoire partage), l'universit de Berkeley a dvelopp une version oriente rseaux en implmentant les protocoles Internet ARPA/DOD et en offrant l'interface des "Sockets".

3.

Concept de socket

Les Sockets forment une API (Application Program Interface): ils offrent aux programmeurs une interface entre le programme d'application et les protocoles de communication. En aucun cas, les sockets ne forment une norme de communication ou une couche de protocole l'instar de TCP/IP. Les sockets (prises de raccordement) forment un mcanisme de communication bidirectionnel interprocessus dans un environnement distribu ce qui n'est pas le cas des autres outils tels que les pipes. Ils permettent videmment la communication interprocess l'intrieur d'un mme systme. L'interface des "sockets" n'est pas lie une pile de protocoles spcifique. Dans ce cours, nous nous intresserons, l'utilisation des sockets dans le monde TCP/IP. La notion de socket en tant que prise de raccordement vient dune analogie avec le rseau lectrique et le rseau tlphonique :

Application

API Sockets

RTC

Rseau lectrique

Rseau informatique

Figure 1 : La mtaphore des prises Les sockets reprsentent donc d'une part une API c'est dire un ensemble de primitives de programmation et d'autre part les extrmits de la communication (notion de prise). Les extrmits de communication sont identifies dans le monde TCP/IP par trois informations : une adresse IP, le protocole utilis (TCP ou UDP) et un numro de port (entier sur 16 bits donc de 0 65535. Etant donn que ces informations sont uniques dans lInternet (les adresses IP sont uniques et les numros de ports sont uniques pour un protocole donn) ces trois informations permettent didentifier de faon unique une extrmit de communication ( linstar dun numro de tlphone dans un rseau tlphonique). Pour maintenir lunicit des numros de port (par protocole) on les a rpartis en trois catgories : - Les ports systmes (appels aussi ports bien connus well known ports) de 0 1023 sont rservs sous UNIX au processus dmarrs automatiquement par le systme dexploitation et peuvent tre dposs auprs de lorganisme IANA (Internet Assigned Numbers Authority). - Les ports utilisateurs (appels aussi ports dposs registered ports) de 1024 49151 sont disponibles pour les utilisateurs et peuvent eux aussi tre dposs auprs de lorganisme IANA. - Les ports dynamiques (appels aussi ports privs) de 49152 65535. Le site web de IANA permet de connatre la liste des ports systmes et utilisateurs assigns un protocole applicatif ou une application donne (http://www.iana.org/assignments/port-numbers). Il propose de plus deux formulaires permettant de dposer des numros de ports systmes ou utilisateurs (http://www.iana.org/cgibin/sys-port-number.pl et http://www.iana.org/cgi-bin/usr-port-number.pl). Pour les TPs il est recommand dutiliser les numros de ports dynamiques. En fonction du protocole transport utilis les sockets vont fonctionner diffremment. Nous prsenterons dans un premier temps les sockets utilisant le protocole TCP qui fonctionnent en utilisant le modle client/serveur et offrent une communication par flux. Les sockets utilisant le protocole UDP seront ensuite prsents. Ils ont un fonctionnement beaucoup plus proche de ce qui se passe au niveau de la couche rseau (change de paquets appels datagrammes dans le monde TCP/IP achemins indpendamment). Les sockets UDP peuvent de plus tre utiliss pour une communication entre une application et un groupe de machine (diffusion plus ou moins restreinte broadcast ou multicast).

4.

Adresses IP

Une machine (appele aussi hte ou host) est identifie dans lInternet par son adresse. Ladresse IP dune machine correspond un numro qui est unique dans le monde. Pour des raisons mnmoniques, il est possible de donner un nom une machine (ex : Toto, Garonne, Mimosa...). Certains htes ont plusieurs noms. Ce nom est gr de faon hirarchique par le DNS (Systme de Noms de Domaines). Ladresse utilise par la version actuelle du protocole IP (adresse IP), comporte deux champs: le champ adresse rseau (Network) dans lInternet et le champ adresse hte (Host) dans le rseau. Sa taille est de 4 octets (32 bits). Elle est souvent donne en notation dcimale pointe (ex: 127.95.35.54). Comme ladresse IP contient ladresse rseau, une station changeant de rseau change dadresse. Dautre part, une station multidomicilie (qui dispose de plusieurs interfaces rseau) ou un routeur ont plusieurs adresses. Il existe actuellement cinq classes dadresses IP. Les trois premires permettent de grer des rseaux de tailles diverses. La classe D permet de grer une communication multipoint (un message est envoy plusieurs machines la fois). La classe E est rserve et ne sera probablement jamais utilise puisquon devrait bientt migrer vers la nouvelle version dIP IPv6 qui stockera les adresses IP dans 16 octets.
Classe A 0 7 bits id. rseau 14 bits id. rseau 21 bits id. rseau 28 bits id. de groupe multicast 27 bits (rserv un usage futur) 24 bits id. hte 16 bits id. hte 8 bits id. hte

Classe B

1 0

Classe C

1 1 0

Classe D

1 1 1 0

Classe E

1 1 1 1 0

Figure 2 : Les classes dadresses IP 4.1. La classe InetAddress La classe java.net.InetAddress permet de reprsenter les adresses IP. Chaque objet de cette classe possde deux champs hostName et address contenant respectivement une chane de caractre et un tableau doctets. Le champ hostName stocke le plus souvent le nom de lhote (www.irit.fr par exemple) et le champ address ladresse IP. Cette classe ne possde pas de constructeur publics. Pour crer un objet de type InetAddress il faut donc utiliser lune des mthodes suivantes :
public static InetAddress getByName (String nom_hote) public static InetAddress [ ] getAllByName (String nom_hote) public static InetAddress getLocalHost ()

4.1.1. public static InetAddress getByName (String nom_hote)

Cette mthode utilise le DNS pour renvoyer une instance de la classe InetAddress reprsentant l'adresse Internet de la machine de nom nom_hote. Voici un exemple dutilisation (en supposant que la classe java.net.InetAddress a t prcdement importe) : InetAddress adr = InetAddress.getByName("www.irit.fr"); Lorsque la recherche DNS n'aboutit pas, une exception UnknownHostException est leve. Exercice : Sachant que InetAddress (comme la plupart des classes Java) surcharge la mthode toString(), crivez un programme crant un objet InetAddress et l'affichant. Testez le programme avec divers noms de machines. Donnez une adresse IP en lieu et place du nom de machine. Que se passe-t-il ?

4.1.2. public static InetAddress [ ] getAllByName (String nom_hote)


Cette mthode renvoie toutes les adresses Internet de la machine de nom nom_hote. Exercice : modifiez le programme prcdent pour rcuprer toutes les adresses d'une machine donne. Essayez de trouver une machine disposant de plusieurs adresses IP.

4.1.3. public static InetAddress getLocalHost ()


Renvoie une instance de la classe InetAddress reprsentant l'adresse Internet de la machine locale. Trs pratique pour tester sur une mme machine les programmes client et serveur. Equivalent getByName (null) ou getByName ("localhost"). Exercice : modifiez le programme prcdent pour afficher en plus l'adresse IP de la machine courante.

4.1.4. Autres mthodes


4.1.4.1. public String getHostName ()

Renvoie le nom de la machine hte, ou bien l'adresse IP si la machine n'a pas de nom. 4.1.4.2. public byte [] getAddress ()

Renvoie l'adresse IP stocke par une instance de la classe InetAddress sous la forme d'un tableau d'octets rangs dans l'ordre standard du rseau (network byte order). Ainsi l'octet d'indice 0 contient l'octet de poids fort de l'adresse. La longueur du tableau retourn est actuellement 4 dans la plupart des cas (IPv4) mais devrait passer 16 lorsque les adresses IP sur 128 bits auront cours (IPv6). Exercice : tentez d'afficher l'aide de votre programme les adresses IP renvoyes par cette mthode. Que remarquez vous ? Remarque : la manipulation d'octets non signs pose des problmes en Java car il n'y a pas d'quivalent au type C unsigned char. Ainsi, les octets suprieurs 127 sont traits comme des nombres ngatifs.

Pour rcuprer les bonnes valeurs il convient de procder comme suit : int octetNonSigne = octet < 0 ? octet + 256 : octet; Exercice : Corrigez votre programme pour afficher correctement les adresses IP renvoyes par getAddress(). 4.1.4.3. Mthodes surcharges

public int hashCode () public boolean equals (Object obj) public String toString () Ces mthodes surchargent celles de la classe Object, pour renvoyer un code de hashing, comparer un objet de classe InetAddress un objet ou renvoyer une chane de caractres dcrivant une adresse Internet. Remarque importante : la premire mthode est directement utilise par la classe InetAddress qui contient une HashTable en membre statique. Ainsi, une adresse requise plusieurs fois sera immdiatement extraite du cache et donc obtenue beaucoup plus rapidement que par l'envoi d'une requte au serveur DNS.

5.

Sockets TCP

5.1. Le modle client/serveur Le protocole TCP offre un service en mode connect et fiable. Les donnes sont dlivres dans lordre de leur
mission.

La procdure dtablissement de connexion est dissymtrique. Un processus, appel serveur, attends des demandes de connexion quun processus, appel client, lui envoie. Une fois ltape dtablissement de connexion effectue le fonctionnement redeviens symtrique. Les deux schmas suivants prsentent les algorithmes de fonctionnement des clients et serveurs. Il est noter que ct serveur on utilise deux sockets : lun, appel socket dcoute, reoit les demandes de connexion et lautre, appel socket de service, sert pour la communication. En effet, un serveur peut tre connect simultanment avec plusieurs clients et dans ce cas on utilisera autant de sockets de service que de clients.

Cration et attachement de la socket dcoute

Ouverture du service

Attente de demande de connexion Cration dune socket de service

Emissions et rceptions de donnes en utilisant la socket de service

Fermeture de la socket de service

Fermeture de la socket dcoute

Fonctionnement du serveur
Cration et attachement de la socket

Construction de ladresse du serveur

Demande de connexion

Echec

Russite

Emissions et rceptions de donnes

Fermeture de la socket

Fonctionnement du client

5.2.

La classe Socket

La classe Socket reprsente en Java les sockets utiliss cts client ou les sockets de service.

5.2.1. Constructeurs
public Socket (String hote, int port) throws UnknownHostException, IOException Ce constructeur cre un socket TCP et tente de se connecter sur le port indiqu de lhte vis. Le premier paramtre de ce constructeur reprsente le nom de la machine serveur. Si lhte est inconnu ou que le serveur de noms de domaine est inoprant, le constructeur gnrera une UnknownHostException. Les autres causes dchec, qui dclenchent lenvoi dune IOException sont multiples : machine cible refusant la connexion sur le port prcis ou sur tous les ports, problme li la connexion Internet, erreur de routage des paquets Voici un exemple dutilisation de ce constructeur :
Socket leSocket = new Socket("www.irit.fr", 80);

public Socket (InetAddress addresse, int port) throws IOException Ce constructeur fonctionne comme le premier, mais prends comme premier paramtre une instance de la classe InetAddress. Ce constructeur provoque une IOException lorsque la tentative de connexion choue mais il ne renvoie pas dUnknownHostException puisque cette information est connue lors de la cration de lobjet InetAddress. public Socket(String hote, int port, InetAddress addresseLocale, int portLocal) throws IOException Comme les deux prcdents, ce constructeur cre un socket et tente de se connecter sur le port indiqu de lhte vis. Le numro du port et le nom de la machine sont fournis dans les deux premiers paramtres et la connexion stablit partir de linterface rseau physique (choix dune carte rseau sur un systme possdant plusieurs accs rseau) ou virtuelle (systme multi-adresse) et du port local indiqus dans les deux derniers paramtres. Si portLocal vaut 0, la mthode (comme les deux premires dailleurs) choisit un port disponible (parfois appel port anonyme) compris entre 1024 et 65 535. Comme la premire mthode cette mthode peut gnrer une IOException en cas de problme de connexion et lorsque le nom dhte donn nest pas correct (il sagit dans ce cas dune UnknownHostException). public Socket(InetAddress address, int port, InetAddress addresseLocale, int portLocal) throws IOException Cette mthode est identique la prcdente la seule diffrence que le premier paramtre est, comme pour la seconde mthode, un objet InetAddress. protected Socket() protected Socket(SocketImpl impl) throws SocketException Ces deux derniers constructeurs sont protgs. Ils crent un socket sans le connecter. On utilise ces constructeurs pour implanter un socket original qui permettra par exemple de chiffrer les transactions ou dinteragir avec un Proxy.

Il existe de plus deux autres constructeurs qui permettent le choix du protocole via un boolen mais ces mthodes sont dprcies et ne doivent pas tre utilises. Pour crer un socket utilisant UDP on utilisera DatagramSocket.

5.2.2. Mthodes informatives


public InetAddress getInetAddress () public int getPort () Ces mthodes renvoient l'adresse Internet et le port distants auquel le socket est connect. public InetAddress getLocalAddress () public int getLocalPort () Ces mthodes renvoient l'adresse Internet et le port locaux que le socket utilise.

5.2.3. Communication avec un socket


public InputStream getInputStream () throws IOException Cette mthode renvoie un flux dentres brutes grce auquel un programme peut lire des informations partir dun socket. Il est dusage de lier cet InputStream un autre flux offrant davantage de fonctionnalits (un DataInputStream par exemple) avant dacqurir les entres. Voici un exemple dutilisation de cette mthode :
DataInputStream fluxEnEntree = new DataInputStream(leSocket.getInputStream());

public OutputStream getOutputStream () throws IOException Cette mthode renvoie un flux de sortie brutes grce auquel un programme peut crire des informations sur un socket. Il est dusage de lier cet OutputStream un autre flux offrant davantage de fonctionnalits (un DataOutputStream par exemple) avant dmettre des donnes. Voici un exemple dutilisation de cette mthode :
DataOutputStream fluxEnSortie = new DataOutputStream(leSocket.getOutputStream());

5.2.4. Fermeture dun socket


public void close() throws IOException Bien que Java ferme tous les sockets ouverts lorsquun programme se termine ou bien lors dun garbage collect , il est fortement conseill de fermer explicitement les sockets dont on na plus besoin laide de la mthode close. Une fois un socket ferm on peut toujours utiliser les mthodes informatives, par contre toute tentative de lecture ou criture sur les input/output streams provoque une IOException.

5.2.5. Options des sockets

Java permet laccs un certain nombre doptions qui modifient le comportement par dfaut des sockets. Ces options correspondent celles que lon manipule en C via ioctl (ou ioctlsocket avec Windows). public boolean getTcpNoDelay() throws SocketException public void setTcpNoDelay(boolean valide) throws SocketException Valide/invalide loption TCP_NODELAY. Valider TCP_NODELAY garantit que les donnes seront expdis aussi rapidement que possible quelle que soit leur taille. Ceci correspond interdire la mise en uvre de lalgorithme de Nagle qui, en simplifiant, concatne les donnes de taille rduite dans des segments de taille suprieure avant envoi. Si lon programme une application trs interactive on pourra valider loption TCP_NODELAY. public int getSoLinger() throws SocketException public void setSoLinger(boolean valide, int secondes) throws SocketException Loption SO_LINGER indique le comportement adopter lorsquil reste des donnes expdier au moment de la fermeture du socket. Par dfaut, la mthode close() rend la main immdiatement et le systme tente denvoyer le reliquat de donnes. Si la dure des prolongations secondes vaut 0 et que valide est vrai, les ventuelles donnes restant sont supprims lorsque la fermeture lieu. Si la dure est positive et que valide est vrai, la mthode close se fige pendant le nombre de secondes spcifies en attendant lexpdition des donnes et la rception de lacquittement. Une fois les prolongations coules, le socket est clos et les donnes restantes ne sont pas transmises. Si cette option nest pas valide (valide est faux) on obtient le comportement par dfaut et lappel de la mthode getSoLinger() retourne 1, sinon la mthode renvoie la dure des prolongations. public int getSoTimeout() throws SocketException public void setSoTimeout(int ms) throws SocketException Par dfaut, lors dune tentative de lecture sur le flux dentre dun socket, read() se bloque jusqu la rception dun nombre doctets suffisant. Lorsque SO_TIMEOUT est initialise, cette attente ne dpasse pas le temps imparti, exprim en millisecondes. Tout dpassement de temps se solde par une une java.net.SocketTimeoutException. Le socket reste malgr tout connect. La valeur par dfaut est 0 qui signifie, ici, un laps de temps infini. Il peut tre prfrable de choisir une dure raisonnable (>0) pour viter que le programme se bloque en cas de problme. Loption doit tre valide avant lappel lopration bloquante pour tre prise en compte. Le paramtre doit tre >= 0 sans quoi une exception SocketException est gnre. public int getSendBufferSize() throws SocketException public void setSendBufferSize(int size) throws SocketException public int getReceiveBufferSize() throws SocketException public void setReceiveBufferSize(int size) throws SocketException Ces mthodes permettent, grce aux options SO_SNDBUF et SO_RCVBUF, de prciser une indication sur la taille allouer aux tampons dentre/sortie bas niveaux. Il sagit uniquement dune indication donc il est conseill aprs lappel dune mthode set dappeler la mthode get correspondante pour vrifier la taille alloue.

5.2.6. Mthode surcharge


public String toString()

La seule mthode surcharge de la classe Object est toString(). Cette mthode provoque laffichage dune chane ressemblant cela :
Socket[addr=amber/192.11.4.2,port=80,localport=1167]

Cette mthode est donc plutt destine au dbogage. 5.3. La classe ServerSocket Cette classe permet de crer des sockets qui attendent des connections sur un port spcifi et lors dune connexion retournent un Socket qui permet de communiquer avec lappelant.

5.3.1. Constructeurs
public ServerSocket (int port) throws IOException Ce constructeur cre un socket serveur qui attendra les connexions sur le port spcifi. Lorsque lentier port vaut 0, le port est slectionn par le systme. Ces ports anonymes sont peu utiliss car le client doit connatre lavance le numro du port de destination. Il faut donc un mcanisme, comme le portmapper des RPC, qui permet dobtenir ce numro de port partir dune autre information. Lechec de la cration se solde par une IOException (ou partir de Java 1.1 une BindException qui hrite de IOException) qui traduit soit lindisponibilit du port choisi soit, sous UNIX, un problme de droits (sous UNIX les ports infrieurs 1024 ne sont disponibles que pour le super utilisateur). public ServerSocket (int port, int tailleFile) throws IOException Ce constructeur permet en outre de prciser la longueur de la file dattente des requtes de connexion. Si une demande de connexion arrive et que la file est pleine la connexion sera refuse sinon elle sera stocke dans la file pour tre traite ultrieurement. La longueur de la file dattente par dfaut (pour le premier constructeur) est 50. Lorsque la valeur donne est suprieure la limite fixe par le systme, la taille maximale est affecte la file. public ServerSocket (int port, int tailleFile, InetAddress adresseLocale) throws IOException Ce constructeur permet en outre de prciser ladresse Internet locale sur laquelle attendre des connexions. Ainsi on pourra choisir lune des interfaces rseau de la machine locale si elle en possde plusieurs. Si adresseLocale est null le socket attendra des connexions sur toutes les adresses locales (ce qui est aussi le cas quand on utilise lun des deux autres constructeurs).

5.3.2. Accepter et clore une connexion


public Socket accept () throws IOException Cette mthode bloque lexcution du programme serveur dans lattente dune demande de connexion dun client. Elle renvoie un objet Socket une fois la connexion tablie. Si vous ne voulez pas bloquer lexcution du programme il suffit de placer lappel accept dans un thread spcifique. public void close () throws IOException

10

Cette mthode ferme le socket serveur en librant le port. Les sockets serveurs sont eux aussi ferms automatiquement par le systme la fermeture de lapplication.

5.3.3. Mthodes informatives


public InetAddress getInetAddress () public int getLocalPort () Ces mthodes renvoient l'adresse Internet et le port locaux sur lequel le socket attends les connexions.

5.3.4. Options des sockets serveurs


Seule loption SO_TIMEOUT est disponible pour les sockets serveurs. public int getSoTimeout() throws SocketException public void setSoTimeout(int ms) throws SocketException Par dfaut, lappel accept() se bloque jusqu la rception dune demande de connexion. Lorsque SO_TIMEOUT est initialise, cette attente ne dpasse pas le temps imparti, exprim en millisecondes. Tout dpassement de temps se solde par une InterruptedException. Le socket reste malgr tout connect. La valeur par dfaut est 0 qui signifie, ici, un laps de temps infini ce qui convient la plupart des serveurs, conus en gnral pour sexcuter indfiniment. Loption doit tre valide avant lappel accept() pour tre prise en compte. Le paramtre doit tre >= 0 sans quoi une exception SocketException est gnre.

5.3.5. Mthode surcharge


public String toString() La seule mthode surcharge de la classe Object est toString(). Cette mthode provoque laffichage dune chane ressemblant cela :
ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=80]

Sous Java 1.1 et les prcdentes versions addr et port sont toujours nulles. La seule information utile est donc localport qui indique le numro du port dattente des connexions. Cette mthode est ici aussi plutt destine au dbogage.

11

5.4.

Exemple de programme client

import java.io.*; import java.net.*; public class ClientEcho extends Object { public static void main (String args[]) { String reponse; Socket leSocket; PrintStream fluxSortieSocket; BufferedReader fluxEntreeSocket; try { // creation dune socket et connexion la machine marine sur le port numro 7 leSocket = new Socket("marine.edu.ups-tlse.fr", 7); System.out.println("Connect sur : "+leSocket); // cration dun fluxSortieSocket // creation dun fluxEntreeSocket flux de type PrintStream li au flux de sortie de la socket = new PrintStream(leSocket.getOutputStream()); flux de type BufferedReader li au flux dentre de la socket = new BufferedReader(new InputStreamReader(leSocket.getInputStream()));

// envoi de donnes vers le serveur fluxSortieSocket.println("Bonjour le monde!"); // attente puis rception de donnes envoyes par le serveur reponse = fluxEntreeSocket.readLine(); System.out.println("Reponse du serveur : " + reponse); leSocket.close(); } // try catch (UnknownHostException ex) { System.err.println("Machine inconnue : "+ex); ex.printStackTrace(); } catch (IOException ex) { System.err.println("Erreur : "+ex); ex.printStackTrace(); } } // main } // class

5.5.

Exemple de programme serveur

import java.io.*; import java.net.*; public class ServeurEcho extends Object { public static void main (String args[]) { ServerSocket socketEcoute; Socket socketService; InputStream entreeSocket;

12

OutputStream

sortieSocket;

try { // cration du socket dcoute (port numro 7) socketEcoute = new ServerSocket(7); while (true) { // attente dune demande de connexion socketService = socketEcoute.accept(); System.out.println("Nouvelle connexion : " + socketService); // rcupration des flux dentre/sortie de la socket de service entreeSocket = socketService.getInputStream(); sortieSocket = socketService.getOutputStream(); try { int b = 0; while (b != -1) { b = entreeSocket.read(); sortieSocket.write(b); } // while System.out.println("Fin de connexion"); } // try catch (IOException ex) { // fin de connexion System.out.println("Fin de connexion : "+ex); ex.printStackTrace(); } socketService.close(); } // while (true) } // try catch (Exception ex) { // erreur de connexion System.err.println("Une erreur est survenue : "+ex); ex.printStackTrace(); } } // main } // class

6.

Sockets UDP

Le protocole UDP offre un service non connect et non fiabilis. Les donnes peuvent tre perdues, dupliques ou
dlivres dans un ordre diffrent de leur ordre dmission.

Le fonctionnement est ici symtrique. Chaque processus cre un socket et lutilise pour envoyer ou attendre et recevoir des donnes. En Java on utilise la classe DatagramPacket pour reprsenter les datagrammes UDP qui sont changs entre les machines. 6.1. La classe DatagramPacket

6.1.1. Constructeurs
public DatagramPacket(byte[] tampon, int longueur)

13

Ce constructeur cre un objet utilis pour recevoir les donnes contenues dans des datagrammes UDP reus par la machine. Le paramtre tampon doit correspondre un tableau doctets (type byte en java) correctement cr (attention si le tableau nest pas assez grand les donnes en excs seront dtruites). Le paramtre longueur indique la longueur du tableau. Exemple dutilisation :
byte[] tampon = new byte[1024]; DatagramPacket datagramme = new DatagramPacket(tampon, tampon.length); public DatagramPacket(byte[] tampon, int longueur, InetAddress adresse, int port)

Ce constructeur cre un objet utilis pour envoyer un datagramme UDP. Le paramtre tampon doit correspondre aux donnes envoyer. Le paramtre longueur doit indiquer la longueur des donnes envoyer. Le paramtre adresse et le paramtre port doivent indiquer respectivement ladresse IP et le port de destination. Il est noter quil existe dautres constructeurs qui permette dindiquer un offset dans un tableau de grande dimension. Ils doivent tre utiliss pour envoyer un tableau dont la taille dpasse la taille maximale des datagrammes IP. Exemple dutilisation :
String message = "Bonjour le monde!"; byte[] tampon = message.getBytes(); InetAddress adresse = InetAddress.getByName("marine.edu.ups-tlse.fr"); DatagramPacket datagramme = new DatagramPacket(tampon, tampon.length, adresse, 7);

6.1.2. Accesseurs
public byte[] getData() public void setData(byte[] buf)

Ces mthodes permettent de rcuprer et de changer le tableau doctets utilis soit pour recevoir soit pour envoyer un datagramme UDP.
public void setLength(int length) public int getLength()

Ces mthodes permettent de rcuprer et de changer la longueur du tableau doctets utilis soit pour recevoir soit pour envoyer un datagramme UDP.
public public public public InetAddress getAddress() void setAddress(InetAddress iaddr) int getPort() void setPort(int iport)

Ces mthodes permettent de rcuprer et de changer les adresses IP et numros de ports. Si lobjet est utilis pour envoyer des datagrammes UDP il sagira de ladresse et du port de destination sinon il sagira de ladresse et du port de lmetteur du datagramme UDP. 6.2. La classe DatagramSocket

6.2.1. Constructeurs
public DatagramSocket() throws SocketException

14

Ce constructeur cre un socket UDP qui permet denvoyer et recevoir des datagrammes UDP. Le port quutilise ce socket est choisi par le systme dexploitation. De mme ladresse IP quutilise ce socket est choisie automatiquement par le systme.
public DatagramSocket(int port) throws SocketException

Ce constructeur cre un socket UDP qui permet denvoyer et recevoir des datagrammes UDP. Le port quutilise ce socket est indiqu par le paramtre port. Ladresse IP quutilise ce socket est choisie automatiquement par le systme.
public DatagramSocket(int port, InetAddress adresse) throws SocketException

Ce constructeur cre un socket UDP qui permet denvoyer et recevoir des datagrammes UDP. Le port quutilise ce socket est indiqu par le paramtre port. Ladresse IP quutilise ce socket est indiqu par le paramtre adresse. Ces trois constructeurs peuvent gnrer des exceptions de type SocketException si il y a un problme de configuration rseau, si le port choisi est dj utilis ou si ladresse choisie nest pas lune des adresses de la machine locale.

6.2.2. Emission et Rception de Datagrammes


public void send(DatagramPacket p) throws IOException

Envoie un datagramme UDP qui contiendra toutes les informations references par lobjet p.
public void receive(DatagramPacket p) throws IOException

Attends un datagramme UDP et lors de sa rception stocke ses informations dans lobjet p. Des exceptions de type IOException peuvent tre gnres si un problme dentre/sortie survient.

6.2.3. Mthodes informatives


public InetAddress getLocalAddress () public int getLocalPort () Ces mthodes renvoient l'adresse Internet et le port locaux que le socket utilise.

6.2.4. Fermeture du socket


public void close() throws IOException Bien que Java ferme tous les sockets ouverts lorsquun programme se termine ou bien lors dun garbage collect , il est fortement conseill de fermer explicitement les sockets dont on na plus besoin laide de la mthode close. Une fois un socket ferm on peut toujours utiliser les mthodes informatives, par contre toute tentative dmission ou de rception de datagrammes UDP provoque une IOException.

15

6.2.5. Options
Comme pour les sockets UDP on peut positionner un certain nombre doptions qui modifient le comportement par dfaut des sockets. public int getSoTimeout() throws SocketException public void setSoTimeout(int ms) throws SocketException Par dfaut, lors dune tentative de rception dun datagramme UDP, receive se bloque jusqu la rception dun datagramme. Lorsque SO_TIMEOUT est initialise, cette attente ne dpasse pas le temps imparti, exprim en millisecondes. Tout dpassement de temps se solde par une java.net.SocketTimeoutException. Le socket reste malgr tout connect. La valeur par dfaut est 0 qui signifie, ici, un laps de temps infini. Il peut tre prfrable de choisir une dure raisonnable (>0) pour viter que le programme se bloque en cas de problme. Loption doit tre valide avant lappel lopration bloquante pour tre prise en compte. Le paramtre doit tre >= 0 sans quoi une exception SocketException est gnre. public int getSendBufferSize() throws SocketException public void setSendBufferSize(int size) throws SocketException public int getReceiveBufferSize() throws SocketException public void setReceiveBufferSize(int size) throws SocketException Ces mthodes permettent, grce aux options SO_SNDBUF et SO_RCVBUF, de prciser une indication sur la taille allouer aux tampons dentre/sortie bas niveaux. Il sagit uniquement dune indication donc il est conseill aprs lappel dune mthode set dappeler la mthode get correspondante pour vrifier la taille alloue.
public void setReuseAddress(boolean on) throws SocketException public boolean getReuseAddress() throws SocketException

Ces methods permettent, grce loption SO_REUSEADDR, de permettre plusieurs sockets dutiliser le mme numro de port. Loption est dsactive par dfaut. Cette option peut tre utilise lors de diffusions (broadcast ou multicast voir aussi la classe suivante). 6.3. La classe MulticastSocket Cette classe permet dutiliser le multicasting IP pour envoyer des datagrammes UDP un ensemble de machines repr grce une addresse multicast (classe D dans IP version 4 : de 224.0.0.1 239.255.255.255).

6.3.1. Constructeurs
Les constructeurs de cette classe sont identiques ceux de la classe DatagramSocket.

6.3.2. Abonnement/rsiliation
Pour pouvoir recevoir des datagrammes UDP envoys grce au multicasting IP il faut sabonner une adresse multicast (de classe D pour IP version 4). De mme lorsquon ne souhaite plus recevoir des datagrammes UDP envoys une adresse multicast on doit indiquer la rsiliation de labonnement.
public void joinGroup(InetAddress adresseMulticast) throws IOException

Cette mthode permet de sabonner ladresse multicast donne. Note : un mme socket peut sabonner plusieurs adresses multicast simultanment. Dautre part il nest pas ncessaire de sabonner une adresse multicast si on veut juste envoyer des datagrammes cette adresse. 16

Une IOException est gnre si ladresse nest pas une adresse multicast ou si il y a un problme de configuration rseau.
public void leaveGroup(InetAddress adresseMulticast) throws IOException

Cette mthode permet de rsilier son abonnement ladresse multicast donne. Une IOException est gnre si ladresse nest pas une adresse multicast, si la socket ntait pas abonne cette adresse ou si il y a un problme de configuration rseau.

6.3.3. Choix du TTL


Dans les datagrammes IP se trouve un champ spcifique appel TTL (Time To Live dure de vie) qui est normalement initialis 255 et dcrment par chaque routeur que le datagramme traverse. Lorsque ce champ atteint la valeur 0 le datagramme est dtruit et une erreur ICMP est envoy lmetteur du datagramme. Cela permet dviter que des datagrammes tournent infiniment lintrieur dun rseau IP. Le multicasting IP utilise ce champ pour limiter la porte de la diffusion. Par exemple avec un TTL de 1 la diffusion dun datagramme est limite au rseau local.
public int getTimeToLive() throws IOException public void setTimeToLive(int ttl) throws IOException

Ces mthodes permettent la consultation et la modification du champ TTL qui sera crit dans les datagrammes envoys par ce socket. 6.4. Exemple de programme qui envoie un datagramme

import java.net.*; import java.io.*; class EnvoiDatagramme { public static void main(String argv[]) throws SocketException, IOException, UnknownHostException { String message = "Bonjour le monde!"; byte[] tampon = message.getBytes(); InetAddress adresse = null; DatagramSocket socket; // recupre ladresse IP de la machine marine adresse = InetAddress.getByName("marine.edu.ups-tlse.fr"); // cre lobjet qui stockera les donnes du datagramme envoyer DatagramPacket envoi= new DatagramPacket(tampon,tampon.length,adresse,50000); // cre un socket UDP (le port est choisi par le systme) socket=new DatagramSocket(); // envoie le datagramme UDP socket.send(envoi); }

17

6.5.

Exemple de programme qui reoit un datagramme

import java.net.*; import java.io.*; class ReceptionDatagramme { public static void main(String argv[]) throws SocketException, IOException { byte[] tampon = new byte[1000]; String texte; // cre un socket UDP qui attends des datagrammes sur le port 50000 DatagramSocket socket =new DatagramSocket(50000); // cre un objet pour stocker les donnes du datagramme attendu DatagramPacket reception = new DatagramPacket(tampon, tampon.length); // attends puis rcupre les donnes du datagramme socket.receive(reception); // rcupre la chane de caractre reue // Note: reception.getLength() contient le nombre doctets reus texte=new String(tampon, 0, reception.getLength()); System.out.println("Reception de la machine "+ reception.getAddress().getHostName()+ " sur le port " +reception.getPort()+" :\n"+ texte ); } }

6.6.

Exemple de programme qui envoie et reoit des datagrammes avec le multicasting IP

import java.net.*; import java.io.*; class MulticastingIP { public static void main(String argv[]) throws SocketException, IOException { String msg = "Bonjour le monde!"; // on traveillera avec ladresse multicast 228.5.6.7 InetAddress groupe = InetAddress.getByName("228.5.6.7"); // cre le socket utilis pour mettre et recevoir les datagrammes // il utilisera le port 50000 MulticastSocket s = new MulticastSocket(50000); // sabonne ladresse IP multicast s.joinGroup(groupe); // cre lobjet qui stocke les donnes du datagramme envoyer DatagramPacket envoi = new DatagramPacket(msg.getBytes(), msg.length(), groupe, 50000); // envoie le datagramme a tout le monde

18

s.send(envoi); while (true) { byte[] tampon = new byte[1024]; DatagramPacket reception = new DatagramPacket(tampon, tampon.length); // attends les rponses s.receive(reception); String texte=new String(tampon, 0, reception.getLength()); System.out.println("Reception de la machine "+ reception.getAddress().getHostName()+ " sur le port " +reception.getPort()+" :\n"+ texte ); } // si la boucle ntait pas infinie on pourrais crire: // s.leaveGroup(groupe); } }

19

Você também pode gostar