 |
 |
15) Informatique distribuée |
|
 |
|
Texte original |
 |
Traducteur :
Jean-Pierre Vidal, Alban Peignier |
|
 |
|
 |
 |
 |
 |
 |
 |
|
 |
05.07.01 - version 1.1 [Armel] : - Ajout des tags de séparation des pages pour le site. 22.08.00 - version 1.0 [Jean-Pierre] : - Dernière version. Traducteur : - Jean-Pierre VIDAL Texte original : -Thinking in Java, 2nd edition, Revision 10 © 2000 by Bruce Eckel
|
 |
 |
 |
15: Distributed Computing
|
 |
15 : Informatique Distribuée
|
 |
 |
 |
Historically, programming across
multiple machines has been error-prone, difficult, and complex.
|
 |
De tous temps, la programmation des machines interconnectées s'est avérée
difficile, complexe, et sujette à erreurs.
|
 |
 |
 |
The programmer had to know many details
about the network and sometimes even the hardware. You usually needed to
understand the various “layers” of the networking protocol, and
there were a lot of different functions in each different networking library
concerned with connecting, packing, and unpacking blocks of information;
shipping those blocks back and forth; and handshaking. It was a daunting
task.
|
 |
Le programmeur devait connaître le réseau de façon détaillée, et parfois
même son hardware. Il était généralement nécessaire d'avoir une bonne compréhension des différentes
couches du protocole réseau, et il existait dans chacune des bibliothèques de réseau un tas de
fonctions, bien entendu différentes, concernant la connexion, l'empaquetage et le dépaquetage des
blocs d'information, l'émission et la réception de ces blocs, la correction des erreurs et le
dialogue. C'était décourageant.
|
 |
 |
 |
However, the basic idea of distributed
computing is not so difficult, and is abstracted very nicely in the Java
libraries. You want to:
|
 |
Toutefois, l'idée de base de l'informatique distribuée n'est pas vraiment
complexe, et elle est encapsulée de manière très agréable dans les bibliothèques Java. Il faut
pouvoir :
|
 |
 |
 |
Get some information
from that machine over there and move it to this machine here, or vice versa.
This is accomplished with basic network
programming.
|
 |
obtenir quelques informations de cette machine-là et les amener sur cette
machine-ci, ou vice versa. Ceci est réalisé au moyen de la programmation réseau de
base ;
|
 |
 |
 |
Connect
to a database, which may live across a network. This is accomplished with
Java DataBase Connectivity (JDBC), which is an abstraction away from the
messy, platform-specific details of SQL (the structured query language
used for most database
transactions).
|
 |
se connecter à une base de données, qui peut résider quelque part sur le
réseau. Pour cela, on utilise la Connectivité Bases de Données Java : Java DataBase
Connectivity (JDBC), qui est une encapsulation des détails confus, et spécifiques à la
plate-forme, du SQL (Structured Query Language - langage structuré d'interrogation de
bases de données - utilisé pour de nombreux échanges avec des bases de données) ;
|
 |
 |
 |
Provide
services via a Web server. This is accomplished with Java’s
servlets and Java Server Pages
(JSPs). |
 |
fournir des services via un serveur Web. C'est le rôle des
servlets Java et des Pages Serveur Java : Java Server Pages
(JSP) ;
|
 |
 |
 |
Execute
methods on Java objects that live on remote machines transparently, as if those
objects were resident on local machines. This is accomplished with Java’s
Remote Method Invocation
(RMI). |
 |
exécuter de manière transparente des méthodes appartenant à des objets Java
résidant sur des machines distantes, exactement comme si ces objets résidaient sur la machine
locale. Pour cela, on utilise l'Invocation de Méthode Distante de Java : Remote Method
Invocation (RMI) ;
|
 |
 |
 |
Use code
written in other languages, running on other architectures. This is accomplished
using the Common Object Request Broker Architecture (CORBA), which is
directly supported by
Java. |
 |
utiliser du code écrit dans d'autres langages, tournant sous d'autres
architectures. C'est l'objet de Common Object Request Broker Architecture (CORBA), qui est
directement mis en oeuvre par Java ;
|
 |
 |
 |
Isolate
business logic from connectivity issues, especially connections with databases
including transaction management and security. This is accomplished using
Enterprise JavaBeans (EJBs). EJBs are not actually a distributed
architecture, but the resulting applications are usually used in a networked
client-server
system. |
 |
séparer les questions relatives à la connectivité de la logique concernant
le résultat cherché, et en particulier les connexions aux bases de données incluant la gestion des
transactions et la sécurité. C'est le domaine des Enterprise JavaBeans (EJB). Les EJB ne
représentent pas réellement une architecture distribuée, mais les applications qui en découlent
sont couramment utilisées dans un système client-serveur en réseau ;
|
 |
 |
 |
Easily,
dynamically, add and remove devices from a network representing a local system.
This is accomplished with Java’s
Jini. |
 |
ajouter et enlever, facilement et dynamiquement, des fonctionnalités
provenant d'un réseau considéré comme un système local. C'est ce que propose la fonctionnalité Jini
de Java.
|
 |
 |
 |
Each topic will be given
a light introduction in this chapter. Please note that each subject is
voluminous and by itself the subject of entire books, so this chapter is only
meant to familiarize you with the topics, not make you an expert (however, you
can go a long way with the information presented here on network programming,
servlets and JSPs).
|
 |
Ce chapitre a pour but d'introduire succinctement toutes ces
fonctionnalités. Il faut noter que chacune représente un vaste sujet, et pourrait faire l'objet
d'un livre à elle toute seule, aussi ce chapitre n'a d'autre but que de vous rendre ces concepts
familiers, et en aucun cas de faire de vous un expert (toutefois, vous aurez largement de quoi
faire avec l'information que vous trouverez ici à propos de la programmation réseau, des servlets
et des JSP).
|
 |
 |
 |
Network programming
|
 |
La programmation réseau
|
 |
 |
 |
One of Java’s great strengths is
painless networking. The Java network library designers have made it quite
similar to reading and writing files, except that the “file” exists
on a remote machine and the remote machine can decide exactly what it wants to
do about the information you’re requesting or sending. As much as
possible, the underlying details of networking have been abstracted away and
taken care of within the JVM and local machine installation of Java. The
programming model you use is that of a file; in fact, you actually wrap the
network connection (a “socket”) with stream objects, so you end up
using the same method calls as you do with all other streams. In addition,
Java’s built-in multithreading is exceptionally handy when dealing with
another networking issue: handling multiple connections at
once.
|
 |
Une des grandes forces de Java est de pouvoir travailler en réseau sans
douleur. Les concepteurs de la bibliothèque réseau de java en ont fait quelque chose d'équivalent à
la lecture et l'écriture de fichiers, avec la différence que les « fichiers » résident
sur une machine distante et que c'est elle qui décide de ce qu'elle doit faire au sujet des
informations que vous demandez ou de celles que vous envoyez. Autant que possible, les menus
détails du travail en réseau ont été cachés et sont pris en charge par la JVM et l'installation
locale de Java. Le modèle de programmation utilisé est celui d'un fichier ; en réalité, la
connexion réseau (Une » socket « - littéralement douille, ou prise, NdT) est encapsulée
dans des objets stream, ce qui permet d'utiliser les mêmes appels de méthode que pour les autres
objets stream. De plus, les fonctionnalités de multithreading de Java viennent à point lorsqu'on
doit traiter plusieurs connexions simultanées.
|
 |
 |
 |
This section introduces Java’s
networking support using easy-to-understand
examples.
|
 |
Cette section introduit le support réseau de Java en utilisant des exemples
triviaux.
|
 |
 |
 |
Identifying a machine
|
 |
Identifier une machine
|
 |
 |
 |
Of course, in order to tell one machine
from another and to make sure that you are connected with a particular machine,
there must be some way of uniquely identifying machines
on a network. Early networks were satisfied to provide unique names for machines
within the local network. However, Java works within the Internet, which
requires a way to uniquely identify a machine from all the others in the
world. This is accomplished with the
IP
(Internet Protocol) address which can exist in two forms:
|
 |
Il semble évident que, pour pouvoir appeler une machine depuis une autre,
en ayant la certitude d'être connecté à une machine en particulier, il doit exister quelque chose
comme un identifiant unique sur le réseau. Les anciens réseaux se contentaient de fournir des noms
de machines uniques sur le réseau local. Mais Java travaille sur l'Internet, et cela nécessite un
moyen d'identifier chaque machine de manière unique par rapport à toutes les autres dans le
monde entier. C'est la raison d'être de l'adresse IP (Internet Protocol - protocole internet,
NdT) qui existe sous deux formes :
|
 |
 |
 |
- The familiarDNS (Domain Name System)
form. My domain name is bruceeckel.com, and if I have a computer called
Opus in my domain, its domain name would be Opus.bruceeckel.com.
This is exactly the kind of name that you use when you send email to people, and
is often incorporated into a World Wide Web address.
- Alternatively, you can use
the “dotted
quad” form, which is four numbers separated by dots, such as
123.255.28.120.
|
 |
- La forme familière la forme DNS (Domain Name System, Système de Nommage des Domaines). Mon nom de domaine est
bruceeckel.com, et si j'avais dans mon domaine un ordinateur nommé
Opus, son nom de domaine serait Opus.bruceeckel.com. C'est
exactement le type de nom que vous utilisez lorsque vous envoyez du courrier à quelqu'un, et il est
souvent associé à une adresse World Wide Web.
- Sinon, on peut utiliser la forme du quadruplet pointé, c'est à dire quatre nombre séparés par des points, par exemple
123.255.28.120.
|
 |
 |
 |
In both cases, the IP address is
represented internally as a 32-bit
number[72] (so each
of the quad numbers cannot exceed 255), and you can get a special Java object to
represent this number from either of the forms above by using the static
InetAddress.getByName( ) method that’s in java.net. The
result is an object of type InetAddress that you can use to build a
“socket,” as you will see later.
|
 |
Dans les deux cas, l'adresse IP est représentée en interne comme un nombre
sur 32 bits [72] (et donc chaque
nombre du quadruplet ne peut excéder 255), et il existe un objet spécial Java pour représenter ce
nombre dans l'une des formes décrites ci-dessus en utilisant la méthode de la bibliothèque
java.net : static
InetAddress.getByName( ). Le résultat est un objet du type
InetAddress qu'on peut utiliser pour construire une socket, « comme on le verra
plus loin.
|
 |
 |
 |
As a simple example of using
InetAddress.getByName( ), consider what happens if you have a
dial-up Internet service provider (ISP). Each time you dial up, you are assigned
a temporary IP address. But while you’re connected, your IP address has
the same validity as any other IP address on the Internet. If someone connects
to your machine using your IP address then they can connect to a Web server or
FTP server that you have running on your machine. Of course, they need to know
your IP address, and since a new one is assigned each time you dial up, how can
you find out what it is?
|
 |
Pour montrer un exemple simple d'utilisation de
InetAddress.getByName( ), considérons ce qui se passe lorsque vous êtes en
communication avec un Fournisseur d'Accès Internet (FAI) - Internet Service Provider (ISP). Chaque
fois que vous vous connectez, il vous assigne une adresse IP temporaire. Tant que vous êtes
connecté, votre adresse IP est aussi valide que n'importe quelle autre adresse IP sur Internet. Si
quelqu'un se connecte à votre machine au moyen de votre adresse IP, alors il peut se connecter à un
serveur Web ou FTP qui tournerait sur votre machine. Bien entendu, il faudrait qu'il connaisse
votre adresse IP, mais puisqu'une nouvelle vous est assignée à chaque connexion, comment
pourrait-il faire ?
|
 |
 |
 |
The following program uses
InetAddress.getByName( ) to produce your IP address. To use it, you
must know the name of your computer. On Windows 95/98, go to
“Settings,” “Control Panel,” “Network,” and
then select the “Identification” tab. “Computer name” is
the name to put on the command line.
|
 |
Le programme qui suit utilise
InetAddress.getByName( ) pour récupérer votre adresse IP. Pour qu'il
fonctionne, vous devez connaître le nom de votre ordinateur. Sous Windows 95/98, aller à
Paramètres, « Panneau de Contrôle, « Réseau, « et sélectionnez l'onglet » Identification. » Le Nom
d'ordinateur est le nom à utiliser sur la ligne de commande.
|
 |
 |
 |
//: c15:WhoAmI.java
// Finds out your network address when
// you're connected to the Internet.
import java.net.*;
public class WhoAmI {
public static void main(String[] args)
throws Exception {
if(args.length != 1) {
System.err.println(
"Usage: WhoAmI MachineName");
System.exit(1);
}
InetAddress a =
InetAddress.getByName(args[0]);
System.out.println(a);
}
} ///:~
|
 |
//: c15:WhoAmI.java // Affiche votre adresse de réseau lorsque // vous êtes connectés à Internet. import java.net.*;
public class WhoAmI { public static void main(String[ « args) throws Exception { if(args.length != 1) { System.err.println( "Usage: WhoAmI MachineName"); System.exit(1); } InetAddress a = InetAddress.getByName(args[0]); System.out.println(a); } } ///:~
|
 |
 |
 |
In this case, the machine is called
“peppy.” So, once I’ve connected to my ISP I run the
program:
|
 |
Supposons que ma machine ait pour nom » peppy. « Une fois connecté au FAI,
je lance le programme :
|
 |
 |
 |
java WhoAmI peppy
|
 |
java WhoAmI peppy
|
 |
 |
 |
I get back a message like this (of
course, the address is different each time):
|
 |
En retour, j'obtiens un message tel que celui-ci (bien entendu, l'adresse
est différente à chaque connexion) :
|
 |
 |
 |
peppy/199.190.87.75
|
 |
peppy/199.190.87.75
|
 |
 |
 |
If I tell my friend this address and I
have a Web server running on my computer, he can connect to it by going to the
URL http://199.190.87.75 (only as long as I continue to stay connected
during that session). This can sometimes be a handy way to distribute
information to someone else, or to test out a Web site configuration before
posting it to a “real”
server.
|
 |
Si je donne cette adresse à un ami et qu'il existe un serveur Web tournant
sur mon ordinateur, il peut s'y connecter en allant à l'URL http://199.190.87.75 (du moins
tant que je reste connecté). Ceci est parfois une manière commode de distribuer de l'information à
d'autres personnes, ou encore de tester la configuration d'un site avant de l'installer sur un
« vrai » serveur.
|
 |
 |
 |
Servers and clients
|
 |
Serveurs et clients
|
 |
 |
 |
The whole point of a network is to allow
two machines to connect and talk to each other. Once the two machines have found
each other they can have a nice, two-way conversation. But how do they find each
other? It’s like getting lost in an amusement park: one machine has to
stay in one place and listen while the other machine says, “Hey, where are
you?”
|
 |
La finalité d'un réseau est de permettre à deux machines de se connecter et
ainsi de se « parler ». Une fois que les deux machines se sont trouvées l'une l'autre,
elles peuvent entamer une agréable conversation bi-directionnelle. Mais qu'est-ce que chacune peut
donc rechercher chez l'autre ? Et d'abord, comment trouvent-elles l'autre ? Tout se passe
à peu près comme lorsqu'on est perdu dans un parc d'attractions : une des machines doit
attendre l'appel de l'autre sans bouger : « Hé, où êtes-vous ? »]
|
 |
 |
 |
The machine that “stays in one
place” is called the
server, and the one that
seeks is called the
client. This distinction
is important only while the client is trying to connect to the server. Once
they’ve connected, it becomes a two-way communication process and it
doesn’t matter anymore that one happened to take the role of server and
the other happened to take the role of the client.
|
 |
La machine qui attend est appelée serveur, celle qui cherche
client. Cette distinction n'est importante que tant que le client cherche à se connecter
au serveur. Une fois les machines connectées, la communication se traduit par un processus
bi-directionnel et on n'a plus à se préoccuper de savoir qui est le serveur et qui est le
client.
|
 |
 |
 |
So the job of the server is to listen for
a connection, and that’s performed by the special server object that you
create. The job of the client is to try to make a connection to a server, and
this is performed by the special client object you create. Once the connection
is made, you’ll see that at both server and client ends, the connection is
magically turned into an I/O stream object, and from then on you can treat the
connection as if you were reading from and writing to a file. Thus, after the
connection is made you will just use the familiar I/O commands from Chapter 11.
This is one of the nice features of Java networking.
|
 |
Le rôle du serveur est donc d'être en attente d'une demande de connexion,
ceci est réalisé par l'objet serveur qu'on crée dans ce but. Le rôle du client est de tenter
d'établir une connexion avec un serveur, ceci est réalisé avec un objet client qu'on crée pour
cela. Une fois la connexion établie, aussi bien du côté serveur que du côté client, elle se
transforme magiquement en un objet flux d'E/S, et dès lors on peut traiter cette connexion comme
une lecture ou une écriture dans un fichier. Ainsi, une fois la connexion établie, il ne reste qu'à
utiliser les commandes d'E/S familières vues au Chapitre 11. C'est un des aspects agréables des
fonctions de Java en réseau.
|
 |
 |
 |
Testing programs without a network
|
 |
Tester les programmes hors réseau
|
 |
 |
 |
For many reasons, you might not have a
client machine, a server machine, and a network available to test your programs.
You might be performing exercises in a classroom situation, or you could be
writing programs that aren’t yet stable enough to put onto the network.
The creators of the Internet Protocol were aware of this issue, and they created
a special address called
localhost to be the
“local loopback” IP
address for testing without a network. The generic way to produce this address
in Java is:
|
 |
Pour toutes sortes de raisons, il se peut qu'on ne dispose pas de machines
client et serveur, pas plus que d'un réseau pour tester nos programmes. Par exemple lorsqu'on
réalise des exercices dans une situation d'apprentissage, ou bien qu'on écrive des programmes qui
ne sont pas encore suffisamment stables pour être mis sur le réseau. Les créateurs du protocole
internet (IP) ont bien appréhendé cette question, et ont créé une adresse spéciale appelée
localhost qui représente une adresse IP en « boucle locale » permettant
d'effectuer des tests en se passant de la présence d'un réseau. Voyez ci-dessous la manière
générique de réaliser cette adresse en Java :
|
 |
 |
 |
InetAddress addr = InetAddress.getByName(null);
|
 |
InetAddress addr = InetAddress.getByName(null);
|
 |
 |
 |
If you hand getByName( ) a
null, it defaults to using the localhost. The InetAddress
is what you use to refer to the particular machine, and you must produce this
before you can go any further. You can’t manipulate the contents of an
InetAddress (but you can print them out, as you’ll see in the next
example). The only way you can create an InetAddress is through one of
that class’s overloaded static member methods
getByName( ) (which is what you’ll usually use),
getAllByName( ), or getLocalHost( ).
|
 |
En utilisant getByName( ) avec un argument
null, cette fonction utilise par défaut localhost.
InetAddress est utilisée pour désigner une machine particulière, et on doit
l'initialiser avant d'aller plus loin. On ne peut pas manipuler le contenu d'une
InetAddress (mais il est possible de l'imprimer, comme on va le voir dans
l'exemple suivant). L'unique manière de créer une InetAddress passe par l'une des
méthodes membre static surchargées de cette classe :
getByName( ) (habituellement utilisée), getAllByName( )
ou getLocalHost( ).
|
 |
 |
 |
You can also produce the local loopback
address by handing it the string localhost:
|
 |
Une autre manière de réaliser l'adresse de la boucle locale est d'utiliser
la chaîne localhost:
|
 |
 |
 |
InetAddress.getByName("localhost");
|
 |
InetAddress.getByName("localhost");
|
 |
 |
 |
(assuming “localhost” is
configured in your machine’s “hosts” table), or by using its
dotted quad form to name the reserved IP number for the
loopback:
|
 |
(en supposant que localhost « est décrit dans la table des hôtes de la
machine), ou encore en se servant de la forme « quadruplet pointé » pour désigner
l'adresse IP réservée à la boucle locale :
|
 |
 |
 |
InetAddress.getByName("127.0.0.1");
|
 |
InetAddress.getByName("127.0.0.1");
|
 |
 |
 |
All three forms produce the same
result.
|
 |
Les trois formes aboutissent au même résultat.
|
 |
 |
 |
Port: a unique place within the machine
|
 |
Les Ports : un emplacement unique dans la machine
|
 |
 |
 |
An IP address isn’t enough to
identify a unique server, since many servers can exist on one machine. Each IP
machine also contains ports, and when you’re setting up a client or
a server you must choose a port
where both client and server agree to connect; if you’re meeting someone,
the IP address is the neighborhood and the port is the bar.
|
 |
Une adresse IP n'est pas suffisante pour identifier un serveur, en effet
plusieurs serveurs peuvent coexister sur une même machine. Chaque machine IP contient aussi des
ports, et lorsqu'on installe un client ou un serveur il est nécessaire de choisir un port
convenant aussi bien à la connexion du client qu'à celle du serveur ; si vous donnez
rendez-vous à quelqu'un, l'adresse IP représentera le quartier et le port sera le nom du
bar.
|
 |
 |
 |
The port is not a physical location in a
machine, but a software abstraction (mainly for bookkeeping purposes). The
client program knows how to connect to the machine via its IP address, but how
does it connect to a desired service (potentially one of many on that machine)?
That’s where the port numbers come in as a second level of addressing. The
idea is that if you ask for a particular port, you’re requesting the
service that’s associated with the port number. The time of day is a
simple example of a service. Typically, each service is associated with a unique
port number on a given server machine. It’s up to the client to know ahead
of time which port number the desired service is running on.
|
 |
Le port n'est pas un emplacement physique dans la machine, mais une
abstraction de programmation (surtout pour des raisons de comptabilité). Le programme client sait
comment se connecter à la machine via son adresse IP, mais comment se connectera-t-il au service
désiré (potentiellement, l'un des nombreux services de cette machine) ? C'est pourquoi les
numéros de port représentent un deuxième niveau d'adressage. L'idée sous-jacente est que si on
s'adresse à un port particulier, en fait on effectue une demande pour le service associé à ce
numéro de port. Un exemple simple de service est l'heure du jour. Typiquement, chaque service est
associé à un numéro de port unique sur une machine serveur donnée. Il est de la responsabilité du
client de connaître à l'avance quel est le numéro de port associé à un service donné.
|
 |
 |
 |
The system services reserve the use of
ports 1 through 1024, so you shouldn’t use those or any other port that
you know to be in use. The first choice for examples in this book will be port
8080 (in memory of the venerable old 8-bit Intel 8080 chip in my first computer,
a CP/M
machine).
|
 |
Les services système réservent les numéros de ports 1 à 1024, il ne faut
donc pas les utiliser, pas davantage que d'autres numéros de ports dont on saurait qu'ils sont
utilisés. Le premier nombre choisi pour les exemples de ce livre est le port 8080 (en souvenir de
la vénérable vieille puce 8 bits Intel 8080 de mon premier ordinateur, une machine
CP/M).
|
 |
 |
 |
Sockets
|
 |
Les sockets
|
 |
 |
 |
The socket is the software
abstraction used to represent the “terminals” of a connection
between two machines. For a given connection, there’s a socket on each
machine, and you can imagine a hypothetical “cable” running between
the two machines with each end of the “cable” plugged into a socket.
Of course, the physical hardware and cabling between machines is completely
unknown. The whole point of the abstraction is that we don’t have to know
more than is necessary.
|
 |
Une socket est une abstraction de programmation représentant les
extrémités d'une connexion entre deux machines. Pour chaque connexion donnée, il existe une socket
sur chaque machine, on peut imaginer un câble virtuel reliant les deux machines, chaque extrémité
enfichée dans une socket. Bien entendu, le hardware sous-jacent ainsi que la manière dont les
machines sont connectées ne nous intéressent pas. L'essentiel de l'abstraction est qu'on n'a pas à
connaître plus que ce qu'il est nécessaire.
|
 |
 |
 |
In Java, you create a socket to make the
connection to the other machine, then you get an InputStream and
OutputStream (or, with the appropriate converters, Reader and
Writer) from the socket in order to be able to treat the
connection as an I/O stream object. There are two stream-based socket classes: a
ServerSocket that a server uses to “listen” for incoming
connections and a Socket that a client uses in order to initiate a
connection. Once a client makes a socket connection, the ServerSocket
returns (via the accept( )
method) a corresponding
Socket through which communications will take place on the server side.
From then on, you have a true Socket to Socket connection and you
treat both ends the same way because they are the same. At this point,
you use the methods
getInputStream( )
and
getOutputStream( )
to produce the corresponding InputStream and OutputStream objects
from each Socket. These must be wrapped inside buffers and formatting
classes just like any other stream object described in Chapter
11.
|
 |
En Java, on crée un objet Socket pour établir une connexion vers une autre
machine, puis on crée un InputStream et un OutputStream (ou, avec
les convertisseurs appropriés, un Reader et un Writer) à partir
de ce Socket, afin de traiter la connexion en tant qu'objet flux d'E/S. Il existe deux classes
Socket basées sur les flux : ServerSocket utilisé par un serveur pour
[écouter « les connexions entrantes et Socket utilisé par un client afin
d'initialiser une connexion. Lorsqu'un client réalise une connexion socket,
ServerSocket retourne (via la méthode accept( )) un
Socket correspondant permettant les communications du côté serveur. À ce
moment-là, on a réellement établi une connexion Socket à Socket
et on peut traiter les deux extrémités de la même manière, car elles sont alors
identiques. On utilise alors les méthodes getInputStream( ) et
getOutputStream( ) pour réaliser les objets InputStream et
OutputStream correspondants à partir de chaque Socket. À leur
tour ils peuvent être encapsulés dans des classes buffers ou de formatage tout comme n'importe quel
objet flux décrit au Chapitre 11.
|
 |
 |
 |
The use of the term ServerSocket
would seem to be another example of a confusing naming scheme in the Java
libraries. You might think ServerSocket would be better named
“ServerConnector” or something without the word “Socket”
in it. You might also think that ServerSocket and Socket should
both be inherited from some common base class. Indeed, the two classes do have
several methods in common, but not enough to give them a common base class.
Instead, ServerSocket’s job is to wait until some other machine
connects to it, then to return an actual Socket. This is why
ServerSocket seems to be a bit misnamed, since its job isn’t really
to be a socket but instead to make a Socket object when someone else
connects to it.
|
 |
La construction du mot ServerSocket est un exemple
supplémentaire de la confusion du plan de nommage des bibliothèques Java.
ServerSocket aurait dû s'appeler « ServerConnector »ou bien n'importe
quoi qui n'utilise pas le mot Socket. Il faut aussi penser que ServerSocket et
Socket héritent tous deux de la même classe de base. Naturellement, les deux
classes ont plusieurs méthodes communes, mais pas suffisamment pour qu'elles aient une même classe
de base. En fait, le rôle de ServerSocketest d'attendre qu'une autre machine se
connecte, puis à ce moment-là de renvoyer un Socket réel. C'est pourquoi
ServerSocket semble mal-nommé, puisque son rôle n'est pas d'être une socket mais
plus exactement de créer un objet Socketlorsque quelqu'un se connecte.
|
 |
 |
 |
However, the ServerSocket does
create a physical “server” or listening socket on the host machine.
This socket listens for incoming connections and then returns an
“established” socket (with the local and remote endpoints defined)
via the accept( ) method. The confusing part is that both of these
sockets (listening and established) are associated with the same server socket.
The listening socket can accept only new connection requests and not data
packets. So while ServerSocket doesn’t make much sense
programmatically, it does “physically.”
|
 |
Cependant, un ServerSocket crée physiquement un » serveur
« ou, si l'on préfère, une « prise » à l'écoute sur la machine hôte. Cette
« prise » est à l'écoute des connexions entrantes et renvoie une « prise »
établie (les points terminaux et distants sont définis) via la méthode
accept( ). La confusion vient du fait que ces deux « prises »
(celle qui écoute et celle qui représente la communication établie) sont associées à la même
« prise » serveur. La « prise » qui écoute accepte uniquement les demandes de
nouvelles connexions, jamais les paquets de données. Ainsi, même si ServerSocket
n'a pas beaucoup de sens en programmation, il en a physiquement.]
|
 |
 |
 |
When you create a ServerSocket,
you give it only a port number. You don’t have to give it an IP address
because it’s already on the machine it represents. When you create a
Socket, however, you must give both the IP address and the port number
where you’re trying to connect. (However, the Socket that comes
back from ServerSocket.accept( ) already contains all this
information.)
|
 |
Lorsqu'on crée un ServerSocket, on ne lui assigne qu'un
numéro de port. Il n'est pas nécessaire de lui assigner une adresse IP parce qu'il réside toujours
sur la machine qu'il représente. En revanche, lorsqu'on crée un Socket, il faut
lui fournir l'adresse IP et le numéro de port sur lequel on essaie de se connecter (toutefois, le
Socket résultant de la méthode ServerSocket.accept( )
contient toujours cette information).
|
 |
 |
 |
A simple server and client
|
 |
Un serveur et un client vraiment simples
|
 |
 |
 |
This example makes the simplest use of
servers and clients using sockets. All the server does is wait for a connection,
then uses the Socket produced by that connection to create an
InputStream and OutputStream. These are converted to a
Reader and a Writer, then wrapped in a BufferedReader and a
PrintWriter. After that, everything it reads from the
BufferedReader it echoes to the PrintWriter until it receives the
line “END,” at which time it closes the connection.
|
 |
Cet exemple montre l'utilisation minimale d'un serveur et d'un client
utilisant des sockets. Le serveur se contente d'attendre une demande de connexion, puis se sert du
Socket résultant de cette connexion pour créer un InputStream et
un OutputStream. Ces derniers sont convertis en Reader et
Writer, puis encapsulés dans un BufferedReader et un
PrintWriter. À partir de là , tout ce que lit le BufferedReader
est renvoyé en écho au PrintWriter jusqu'à ce qu'il reconnaisse la ligne » END, «
et dans ce cas il clôt la connexion.
|
 |
 |
 |
The client makes the connection to the
server, then creates an OutputStream and performs the same wrapping as in
the server. Lines of text are sent through the resulting PrintWriter. The
client also creates an InputStream (again, with appropriate conversions
and wrapping) to hear what the server is saying (which, in this case, is just
the words echoed back).
|
 |
Le client établit une connexion avec le serveur, puis crée un
OutputStreamet réalise le même type d'encapsulation que le serveur. Les lignes de
texte sont envoyées vers le PrintWriterrésultant. Le client crée également un
InputStream (ici aussi, avec la conversion et l'encapsulation appropriées) afin
d'écouter le serveur (c'est à dire, dans ce cas, simplement les mots renvoyés en écho).
|
 |
 |
 |
Both the server and client use the same
port number and the client uses the local loopback address to connect to the
server on the same machine so you don’t have to test it over a network.
(For some configurations, you might need to be connected to a network for
the programs to work, even if you aren’t communicating over that
network.)
|
 |
Le serveur ainsi que le client utilisent le même numéro de port, et le
client se sert de l'adresse de boucle locale pour se connecter au serveur sur la même machine, ce
qui évite de tester en grandeur réelle sur un réseau (pour certaines configurations, on peut être
amené à se connecter physiquement à un réseau afin que le programme fonctionne, même si on
ne communique pas sur ce réseau.)
|
 |
 |
 |
Here is the server:
|
 |
Voici le serveur :
|
 |
 |
 |
//: c15:JabberServer.java
// Very simple server that just
// echoes whatever the client sends.
import java.io.*;
import java.net.*;
public class JabberServer {
// Choose a port outside of the range 1-1024:
public static final int PORT = 8080;
public static void main(String[] args)
throws IOException {
ServerSocket s = new ServerSocket(PORT);
System.out.println("Started: " + s);
try {
// Blocks until a connection occurs:
Socket socket = s.accept();
try {
System.out.println(
"Connection accepted: "+ socket);
BufferedReader in =
new BufferedReader(
new InputStreamReader(
socket.getInputStream()));
// Output is automatically flushed
// by PrintWriter:
PrintWriter out =
new PrintWriter(
new BufferedWriter(
new OutputStreamWriter(
socket.getOutputStream())),true);
while (true) {
String str = in.readLine();
if (str.equals("END")) break;
System.out.println("Echoing: " + str);
out.println(str);
}
// Always close the two sockets...
} finally {
System.out.println("closing...");
socket.close();
}
} finally {
s.close();
}
}
} ///:~
|
 |
//: c15:JabberServer.java // Serveur simplifié dont le rôle se limite à // renvoyer en écho tout ce que le client envoie. import java.io.*; import java.net.*;
public class JabberServer { // Choisir un port hors de la plage 1-1024: public static final int PORT = 8080; public static void main(String[ « args) throws IOException { ServerSocket s = new ServerSocket(PORT); System.out.println("Started: " + s); try { // Le programme stoppe ici et attend // une demande de connexion: Socket socket = s.accept(); try { System.out.println( "Connection accepted: "+ socket); BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream())); // Le tampon de sortie est vidé // automatiquement par PrintWriter: PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter( socket.getOutputStream())),true); while (true) { String str = in.readLine(); if (str.equals("END")) break; System.out.println("Echoing: " + str); out.println(str); } // Toujours fermer les deux sockets... } finally { System.out.println("closing..."); socket.close(); } } finally { s.close(); } } } ///:~
|
 |
 |
 |
You can see that the ServerSocket
just needs a port number, not an IP address (since it’s running on
this machine!). When you call accept( ), the method
blocks until some client tries to connect to it. That is, it’s
there waiting for a connection, but other processes can run (see Chapter 14).
When a connection is made, accept( ) returns with a Socket
object representing that connection.
|
 |
On remarque que ServerSocket ne nécessite qu'un numéro de
port, et non une adresse IP (puisqu'il tourne sur cette machine !). Lorsqu'on appelle
accept( ) la méthode bloque jusqu'à ce qu'un client tente de se
connecter. Cela signifie qu'elle est en attente d'une demande de connexion, mais elle ne bloque pas
les autres processus (voir le Chapitre 14). Une fois la connexion établie,
accept( ) renvoie un objet Socket qui représente cette
connexion.
|
 |
 |
 |
 |
 |
 |
 |
 |
|
 |
 |
 |