Cet exemple partage le code d'implémentation spécifique pour la lecture de la connexion et du téléchargement du serveur pour votre référence. Le contenu spécifique est le suivant
Le client s'exécute sur un serveur qui fournit à l'utilisateur des services UNIX. Utilisé pour lire et collecter les informations en amont et en aval des utilisateurs sur le serveur, les paire et les organiser, puis les envoyer au serveur pour résumé.
Code d'implémentation spécifique:
1. Dmsserver.java
package com.dms; Importer java.io.bufferedReader; import java.io.file; import java.io.fileoutputStream; import java.io.ioException; import java.io.inputStreamreader; import java.io.outputstreamwriter; import java.io.printwriter; import java.net.net.servers; java.util.hashmap; importer java.util.list; import java.util.map; import java.util.concurrent.blocksqueue; import java.util.concurrent.executervice; import java.util.concurrent.execuue; import org.dom4j.document; import org.dom4j.element; import org.dom4j.io.saxreader; / ** * DMS Server, utilisé pour recevoir * des journaux de couple envoyés par chaque client et les enregistrer dans un fichier local * @Author Administrator * * / public class dmsserver {// Définition de propriétés // ServerSocket Server Server Server utilisé pour recevoir le serveur connecté au client; // Pool de threads utilisé pour gérer les threads qui gèrent les demandes du client File ExecutorService Threadpool; // Enregistrer tous les fichiers envoyés par les clients pour paire des journaux de journaux Private File ServerLogFile; // Fitre de message Private BlockingQueue <string> MessageQueue = new LinkedBlockingQueue <string> (); public dmsServer () lève une exception {try {System.out.println ("Le serveur initialise ..."); // 1 analyse le fichier de configuration Server-Config.xml Map <String, String> config = loshConfig (); // 2 Initialiser l'attribut init (config); System.out.println ("Initialisation du serveur terminée ..."); } catch (exception e) {System.out.println ("L'initialisation a échoué!"); jeter e; }} / ** * La première étape de l'initialisation de la méthode du constructeur consiste à analyser le fichier de configuration * @return La carte renvoyée est enregistrée dans chaque élément du fichier de configuration, où la clé: le nom de la balise, * la valeur est le texte au milieu de la balise * @throws exception * / private map <string <string> loadConfig () Throws exception {try {saxreader Reader = new SAXREAR (); Document doc = reader.read (nouveau fichier ("server-config.xml")); Élément root = doc.getrootelement (); Map <string, string> config = new hashmap <string, string> (); / * * Obtenez tous les sous-étiquettes dans la balise <FIGIG> et enregistrez le nom de chaque sous-tag comme la clé, et le * texte au milieu est la valeur dans la collection de cartes * / list <element> list = root.Elements (); pour (élément e: list) {string key = e.getName (); String value = e.getTextTrim (); config.put (clé, valeur); } return config; } catch (exception e) {System.out.println ("Résoudre l'exception du fichier de configuration!"); e.printStackTrace (); jeter e; }} / ** * La deuxième étape de l'initialisation de la méthode du constructeur consiste à initialiser l'attribut en fonction de l'élément de configuration * @param config * @throws exception * / private void init (map <string, string> config) lève une exception {/ * * Initialiser l'attribut avec <bogrecfile> dans le fichier de configuration: Serverlogfile * Initialiser la propriété: Threadpool avec <relersum> créé. Cette valeur est utilisée comme nombre de threads de filetage de threads * Initialisez la propriété avec le <serverport> dans le fichier de configuration: serveur, ici cette valeur est le port de serveur de Serversocket * / this.server = new serversocket (Integer.Parseint (config.get ("serverport"))))); this.serverLogFile = new File (config.get ("LOGRECFILE")); this.Threadpool = exécutors.newFixEdThreadPool (Integer.ParseInt (config.get ("ThreadSum"))); } / ** * Méthode pour commencer à travailler sur le serveur * @throws exception * / public void start () lève l'exception {/ * * Exigences d'implémentation: * Démarrez d'abord un thread séparément pour exécuter le SavelogHandler * Cette tâche consiste à enregistrer tous les journaux de couplage *, puis à commencer à écouter la boucle des ports du serveur. Une fois qu'un client est connecté, * instancier un clienthander, puis remettre la tâche au pool de threads * pour attribuer des threads pour gérer l'interaction avec le client. * * / try {System.out.println ("Le serveur commence à fonctionner ..."); SavelogHandler slh = new SavelogHandler (); nouveau thread (slh) .start (); while (true) {socket socket = server.accept (); threadpool.exécute (new ClientHandler (socket)); }} catch (exception e) {e.printStackTrace (); jeter e; }} public static void main (string [] args) {try {dmsserver server = new dmsserver (); server.start (); } catch (exception e) {System.out.println ("La station n'a pas démarré le serveur!"); }}} / ** * Ce thread est responsable de la récupération de chaque journal apparié de la file d'attente de messages, * et de l'enregistrement dans le fichier ServerLogFile * @Author Administrator * * / private class SavelogHandler implémente Runnable {public void run () {printwriter pw = null; essayez {pw = new printwriter (new FileOutputStream (serverLogFile, true)); while (true) {if (MessageQueue.size ()> 0) {pw.println (messageQueue.poll ()); } else {pw.flush (); Thread.Sleep (500); }}} catch (exception e) {e.printStackTrace (); } enfin {if (pw! = null) {pw.close (); }}}}} / ** * gérer une demande client spécifiée * @Author Administrator * * / Class Private ClientHandler implémente Runnable {private socket socket; ClientHandler public public (socket socket) {this.socket = socket; } public void run () {/ * * IDEA: * Recevez d'abord tous les journaux appariés envoyés par le client, * jusqu'à "Over", puis enregistrez ces journaux appariés * dans le fichier local, et répondez au client * "OK" * Exécutez les étapes: * 1: Créez un flux de sortie via la prise pour envoyer une réponse au client * 2: Créer un flux d'entrée par le client, il est d'abord envoyé par le client * 3: Lire chaque chaîne String "Over". Sinon, il s'agit d'un journal apparié et enregistrez-le dans le fichier local. Si oui, * Arrêtez de lire. * 4: Répondre au client "OK" après avoir réussi à lire tous les journaux * / printwriter pw = null; try {// 1 pw = new printwriter (new OutputStreamWriter (socket.getOutputStream (), "utf-8")); // 2 BufferedReader br = new BufferedReader (new inputStreamReader (socket.getInputStream (), "utf-8")); // Message de chaîne = null; while ((message = br.readline ())! = null) {if ("over" .equals (message)) {break; } // Écrivez le journal dans un fichier pour enregistrer MessageQueue.offer (message); } // 4 pw.println ("ok"); pw.flush (); } catch (exception e) {e.printStackTrace (); pw.println ("erreur"); pw.flush (); } enfin {try {// Débrancher du client pour libérer le socket de ressources.close (); } catch (ioException e) {e.printStackTrace (); }}}}}}}}}}}}} 2. Dmsclient.java
package com.dms; Importer java.io.bufferedReader; import java.io.file; import java.io.ioException; import java.io.inputstreamreader; import java.io.outputstreamwriter; import java.io.printwriter; import java.io.randomaccessfile; import java.net.netchen; java.util.hashmap; import java.util.list; import java.util.map; import java.util.map.entry; import java.util.set; import org.dom4j.document; import org.dom4j.element; import org.dom4j.io.saxreader; import com.dms.bo.logdata; import com.dms.bo.logrec; / ** * Ce client s'exécute sur le serveur qui fournit aux utilisateurs des services UNIX. * Utilisé pour lire et collecter les informations en amont et en aval des utilisateurs sur le serveur, et * paire et trier et les envoyer au serveur pour résumé. * @Author Administrator * * / public class dmsClient {// Définition d'attribut // Étape 1: analyse les propriétés requises du fichier journal du système log // Unix fichier de journal privé de fichier de fichiers; // Enregistrer le fichier du journal privé du journal analysé TextLogFile; // Bookmark Fichier Private Fichier LastPositionFile; // Numéro d'entrées pour chaque logarid Private int lot; // Étape 2: Associez les attributs du journal // Enregistrer le fichier Private File LOGRECFILE; // Enregistrer le fichier Fichier privé LoginLogFile; // Étape 3: Analyser les attributs de l'adresse log // du serveur Private String ServerHost; // Port de serveur private int serverport; / ** * Méthode du constructeur, utilisée pour initialiser le client * @throws exception * / public dmsclient () lève l'exception {try {// 1 analyse le fichier de configuration config.xml map <string, string> config = loadConfig (); // Piling System.out.println (config); // 2 Initialiser l'attribut init (config); } catch (exception e) {System.out.println ("L'initialisation a échoué!"); jeter e; }} / ** * Initialisez la deuxième étape de la méthode du constructeur, initialisez les attributs en fonction de l'élément de configuration * @param config * @throws exception * / private void init (map <string, string> config) lève exception {try {logfile = nouveau file (config.get ("logfile")); textLogFile = nouveau fichier (config.get ("textLogFile")); LastPositionFile = nouveau fichier (config.get ("LastPositionFile")); Batch = Integer.ParseInt (config.get ("Batch")); LOGRECFILE = nouveau fichier (config.get ("LOGRECFILE")); loginLogFile = new File (config.get ("loginlogfile")); serverhost = config.get ("serverhost"); serverport = Integer.ParseInt (config.get ("serverport")); } catch (exception e) {System.out.println ("La propriété d'initialisation a échoué!"); e.printStackTrace (); jeter e; }} / ** * La première étape de l'initialisation de la méthode du constructeur consiste à analyser le fichier de configuration * @return La carte retournée est enregistrée dans chaque élément du fichier de configuration, où la clé: le nom de la balise, * la valeur est le texte au milieu de la balise * @throws exception * / private map Document doc = reader.read (nouveau fichier ("config.xml")); Élément root = doc.getrootelement (); Map <string, string> config = new hashmap <string, string> (); / * * Obtenez tous les sous-étiquettes dans la balise <FIGIG> et utilisez le nom de chaque sous-tag comme la clé, le * dans le texte du milieu est stocké dans la collection de cartes sous forme de valeur * / list <element> list = root.Elements (); pour (élément e: list) {string key = e.getName (); String value = e.getTextTrim (); config.put (clé, valeur); } return config; } catch (exception e) {System.out.println ("Exception du fichier de configuration d'analyse!"); e.printStackTrace (); jeter e; }} / ** * Méthode pour que le client commence à travailler * trois étapes de la boucle: * 1: l'analyse du journal * 2: Journage du journal * 3: Envoyer le journal * / public void start () {Parselogs (); MatchLogs (); sendLogs (); // while (true) {// // parse log // if (! parselogs ()) {// continue; //} // // jumelle du journal /// if (! MatchLogs ()) {// continue; //} // // Envoi du log * Échec * / private booléen sendlogs () {/ * * Idea Idea: * Lisez tous les journaux appariés dans le fichier LOGRECFILE * et connectez-vous au serveur et envoyez-le, si le serveur * Si vous les recevez tous, vous pouvez supprimer le fichier, ce qui signifie que l'envoi * est terminé. * Étapes d'implémentation: * 1: Le fichier LOGRECFILE doit exister * 2: Lisez et stockez tous les journaux appariés dans une collection * Attendez l'envoi * 3: Connectez-vous au serveur via Socket * 4: Créez un flux de sortie * 5: Envoyez tous les journaux appariés en séquence au serveur en ligne * 6: Envoyez une chaîne unique "sur" pour indiquer que tous les journaux * ont été envoyés: Créer un flux d'entrée * 8: Lire la chaîne de réponse Back par le serveur * 9: Créer un flux d'entrée * 8: "OK", cela signifie que le serveur est normal * a reçu tous les journaux, puis le fichier LOGRECFILE * peut être supprimé et renvoyé vrai signifie que l'envoi est terminé. * * / Socket socket = null; essayez {// 1 if (! LOGRECFile.exists ()) {System.out.println (LOGRECFILE + "NON EXIST!"); retourne false; } // 2 list <string> correspond = ioutil.loadLogrec (loggrecfile); // 3 socket = new socket (serverhost, serverport); // 4 printwriter pw = new printwriter (new OutputStreamWriter (socket.getOutputStream (), "utf-8")); // 5 pour (String Log: correspond) {pw.println (log); } // 6 pw.println ("over"); pw.flush (); // 7 BufferedReader br = new BufferedReader (new inputStreamReader (socket.getInputStream (), "utf-8")); // 8 chaînes réponse = br.readline (); // 9 if ("ok" .equals (réponse)) {LOGRECFILE.DELETE (); Retour Vrai; } else {System.out.println ("Envoyer un journal échoué!"); retourne false; }} catch (exception e) {System.out.println ("Envoyer un journal échoué!"); e.printStackTrace (); } enfin {if (socket! = null) {try {socket.close (); } catch (ioException e) {e.printStackTrace (); }} return false; } / ** * Étape 2: Associez le journal * @return True: Association avec succès * FAUX: FAILLEMENT ÉCHEUS * / PRIVATE BOOLEAN MATCHLOGS () {/ * * Implémentation Idea: * Lisez tous les nouveaux journaux analysés dans la première étape avec le journal de connexion qui a été le dernier couplé avec succès *, puis suivre l'utilisateur, * Le même pière, l'un est 7 et l'autre pour le jumelage. * Tant que vous pouvez trouver un type 8, vous pouvez trouver un journal de connexion qui peut être associé à *. * * Étapes de mise en œuvre: * 1: Jugement nécessaire * 1.1: si LOGRECFILE existe. S'il existe, ce ne sera plus * de nouveaux travaux d'appariement seront effectués pour éviter l'écrasement. * 1.2: le fichier textlogfile doit exister. * 2: Lisez TextLogFile et lisez les journaux et * à la collection. (Plusieurs instances de logdata) * 3: Si le fichier LoginLogFile existe, cela signifie * Il y a un journal qui n'a pas été jumelé avec succès la dernière fois, et il est également lu * et enregistré dans la collection en attendant d'être jumelé ensemble * 4: Pailing Work * 4.1: Créer une collection pour enregistrer tous Connexion et déconnexion * * où la clé: utilisateur, PID * Valeur: Instance logdata * 4.4: Traversez la carte de déconnexion et recherchez le journal de connexion correspondant dans la carte de connexion en fonction de la clé * de chaque journal de déconnexion, et * Enregistrez le connexion appariée dans l'ensemble des journaux appariés. Et supprimez le journal de connexion dans le journal apparié * de la carte de connexion. De cette façon, ** Vous ne devez avoir plus de couple que lorsque vous vous connectez à la carte. * 5: Écrivez des journaux appariés à LOGRECFILE * 6: Écrivez tous les journaux non appariés à LoginLogFile * 7: Supprimer le fichier TextLogFile * 8: Return True, indiquant que l'appariement est terminé * * / try {// 1 //1.1 if (logrecfile.exists ()) {return true; } //1.2 if (! TextLogFile.exists ()) {System.out.println (TextLogFile + "NON EXIST!"); retourne false; } // 2 list <logdata> list = ioutil.loadLogData (textLogFile); // 3 if (loginlogfile.exists ()) {list.addall (ioutil.loadLogData (loginlogfile)); } // 4 //4.1 Liste <LOGREC> MATCHES = NOUVEAU ARRAYLIST <NOGREC> (); //4.2 map <string, logdata> loginmap = new hashmap <string, logdata> (); Map <string, logdata> logoutmap = new hashmap <string, logdata> (); //4.3 pour (logdata logdata: list) {string key = logdata.getUser () + "," + logdata.getpid (); if (logdata.getType () == logdata.type_login) {loginmap.put (key, logdata); } else if (logdata.getType () == logdata.type_logout) {logoutmap.put (key, logdata); }} //4.4 set <entrée <string, logdata >> entrySet = logoutmap.entryset (); pour (entrée <chaîne, logdata> e: entryset) {logdata logout = e.getValue (); LogData Login = LoginMap.Remove (E.GetKey ()); LOGREC LOGREC = NOUVEAU LOGREC (Login, Logout); matches.add (logrec); } // 5 ioutil.saveCollection (matchs, logrecfile); // 6 ioutil.saveCollection (loginmap.values (), loginlogfile); // 7 textLogFile.Delete (); // 8 retour true; } catch (exception e) {System.out.println ("Le journal de couple a échoué!"); e.printStackTrace (); } return false; } / ** * Étape 1: Parse the Log * @return True: Parse réussi * False: Parse échoué * / private booléen Parselogs () {/ * * Implémentation Idea: * Loop Reading Lot Journaux, puis analyse * 5 informations dans chaque journal, et enfin former une chaîne, l'écrivez dans le fichier TextLogfile dans le commandement de la connexion * * Implémentation étapes: * 1: Pourtant, et * la première étape répète l'exécution, ce qui fait écraser le journal précédent *, vous devez juger ici. Si vous enregistrez le journal analysé *, le fichier journal existe et que la première étape ne sera plus exécutée. * Ce fichier journal sera supprimé après la deuxième étape. * 1.2: le fichier de fichiers de journaux doit exister (fichier wtmpx) * 1.3: y a-t-il encore un journal qui peut être analysé * 2: Créez un RandomAccessFile pour lire le fichier de journal * 3: déplacez le pointeur vers la dernière position de lecture, préparez * Démarrez un nouveau travail d'analyse * 4: Parsing Work * 4.1: Créer une collection de liste pour enregistrer chaque connexion (Instruction logdata) * 4.2: Loop. Dans chaque journal (utilisateur, PID, type, temps, hôte) * et enregistrez-le avec une instance logdata, puis enregistrez * l'instance logdata dans la collection * 5: Enregistrez tous les journaux de la collection dans les unités de comportement à * textlogfile * 6: Enregistrer les informations de bibliothèque * 7: return true, indiquant que le travail est terminé * * * / RandomAccessFile Raf = Null; essayez {// 1 //1.1 if (textLogFile.exists ()) {return true; } //1.2 if (! Logfile.exists ()) {System.out.println (logfile + "pas exister!"); retourne false; } //1.3 LONGERPOSITION LONNE = HASLOGS (); // Piling // System.out.println (// "LastPosition:" + LastPosition //); if (LastPosition <0) {System.out.println ("Aucun journal ne peut être analysé!"); retourne false; } // 2 raf = new randomaccessfile (logfile, "r"); // 3 raf.seek (LastPosition); // 4 list <logdata> list = new ArrayList <RogData> (); pour (int i = 0; i <lot; i ++) {// Avant chaque analyse, déterminez s'il existe encore des journaux qui peuvent être analysés if (logfile.length () - LastPosition <logdata.log_length) {break; } // Parse User raf.seek (LastPosition + LogData.user_offset); String user = ioutil.readString (RAF, logdata.user_length) .trim (); // analyse pid raf.seek (LastPosition + LogData.pid_offset); int pid = raf.readInt (); // Type d'analyse raf.seek (LastPosition + LogData.type_offset); Type court = raf.readshort (); // analyse Time RAF.seek (LastPosition + LogData.Time_Offset); int time = raf.readInt (); // Collez l'hôte RAF.seek (LastPosition + LogData.host_offset); String host = ioutil.readString (raf, logdata.host_length) .trim (); Logdata log = new LogData (utilisateur, pid, type, temps, hôte); list.add (log); // Piling // System.out.println (log); // Télécharger un journal, mettre à jour LastPosition LastPosition = raf.getFilePointer (); } // 5 ioutil.saveCollection (list, textLogFile); // 6 Enregistrer le fichier Fichier ioutil.savelong (LastPosition, LastPositionFile); // 7 Retour True; } catch (exception e) {System.out.println ("Le journal de passage a échoué!"); e.printStackTrace (); } enfin {if (raf! = null) {try {raf.close (); } catch (ioException e) {e.printStackTrace (); }} return false; } / ** * La première étape consiste à analyser un lien dans le journal. * Selon l'emplacement de l'enregistrement du fichier de signets, déterminez s'il y a encore * log à analyser. S'il y en a, la dernière position * sera retournée. S'il n'y a pas, retourz -1. * @return * / private long Haslogs () {try {/ * * Si LastPositionFile n'existe pas, cela signifie * n'a jamais été analysé, vous pouvez donc analyser à partir de zéro * / if (! LastPositionFile.exists ()) {return 0; } long LastPosition = ioutil.readlong (LastPositionFile); if (logfile.length () - LastPosition> = logdata.log_length) {return lastPosition; }} catch (exception e) {e.printStackTrace (); } return -1; } public static void main (string [] args) {try {dmsclient client = new dmsClient (); client.start (); } catch (exception e) {System.out.println ("Client Run a échoué!"); }}} 3. ioutil.java
package com.dms; Importer java.io.bufferedReader; import java.io.file; import java.io.fileInputStream; import java.io.inputstreamreader; import java.io.printwriter; import java.io.randomAccessfile; import java.util.arraylist; import java.util.collection; import java.util. com.dms.bo.logdata; / ** * Cette classe est une classe d'outils responsable des opérations IO du client * @Author Administrator * * / public class ioutil {/ ** * Lisez chaque ligne de chaîne à partir du fichier donné (journal de paire) * et enregistrez une collection à retourner * @param fichier * @return * @throws exception * / public static list <string> loadLogrec (fichier file) exception {BuffredReader br = Null; try {br = new BufferedReader (new inputStreamReader (new FileInputStream (fichier))); List <string> list = new ArrayList <string> (); Chaîne line = null; while ((line = br.readline ())! = null) {list.add (line); } Retour List; } catch (exception e) {e.printStackTrace (); jeter e; } enfin {if (br! = null) {br.close (); }}} / ** * Lisez chaque journal apparié du fichier donné et enregistrez-le dans * une collection, puis retournez. * @param fichier * @return * @throws exception * / public static list <logdata> hostlogData (fichier file) lève exception {bufferedReader br = null; try {br = new BufferedReader (new inputStreamReader (new FileInputStream (fichier))); List <logdata> list = new ArrayList <RogData> (); Chaîne line = null; while ((line = br.readline ())! = null) {logdata logdata = new logdata (line); list.add (logdata); } Retour List; } catch (exception e) {e.printStackTrace (); jeter e; } enfin {if (br! = null) {br.close (); }}} / ** * Écrivez la valeur longue spécifiée dans la première ligne du fichier donné en tant que chaîne * @param l * @param fichier * @throws exception * / public static void savelong (long lon, fichier file) lève une exception {printwriter pw = null; essayez {pw = new printwriter (fichier); pw.println (lon); } catch (exception e) {e.printStackTrace (); jeter e; } enfin {if (pw! = null) {pw.close (); }}}} / ** * Écrivez la chaîne renvoyée par la méthode ToString de chaque élément de la collection dans le fichier spécifié dans les unités de comportement. * @param c * @param fichier * @throws exception * / public static void saveCollection (collection c, fichier de fichier) lève une exception {printwriter pw = null; essayez {pw = new printwriter (fichier); pour (objet o: c) {pw.println (o); }} catch (exception e) {e.printStackTrace (); jeter e; } enfin {if (pw! = null) {pw.close (); }}} / ** * Démarrer continu à partir de la position actuelle du RandomAccessFile * donné * Lire des octets de longueur et les convertir en une chaîne et renvoyer * @param raf * @param longueur * @return * @throws exception * / public static string readstring (randomaccessfile raf, int longueur) lance exception {try {Byte [] data = new Byte [longueur]; raf.read (données); return new String (data, "iso8859-1"); } catch (exception e) {e.printStackTrace (); jeter e; }} / ** * Lisez la première ligne de chaîne à partir du fichier donné, puis * RETOUR * @Param File * @return * @throws Exception * / public static Long readlong (fichier file) lève l'exception {BuffereDreader br = null; try {br = new BufferedReader (new inputStreamReader (new FileInputStream (fichier))); String Line = Br.Readline (); retour long.parselong (ligne); } catch (exception e) {e.printStackTrace (); jeter e; } enfin {if (br! = null) {br.close (); }}}}
4. config.xml
<? xml version = "1.0" Encoding = "UTF-8"?> <FIFIG> <! - UNIX System System Log Name -> <logfile> wtmpx </ logfile> <! - Enregistrez le nom de fichier journal résolu -> <TextLogFile> Log.txt </ textlogfile> <! - Nom de fichier de buckmark -> <dernierPositionFile> Last-pososition.Txt. Nombre d'entrées par journal analysé -> <batch> 10 </ batch> <! - Nom du fichier journal apparié -> <golecFile> LOGREC.TXT </ LOGRECFILE> <! - Nom du fichier journal non apparié -> <ginginlogfile> Login.txt </ LoginlogFile> <! <y!
5. Server-Config.xml
<? xml version = "1.0" Encoding = "UTF-8"?> <FIFIG> <! - Nom de fichier du serveur qui enregistre le fichier journal apparié -> <LOGRECFILE> Server-Logs.txt </ LOGRECFILE> <! - Nombre de threads Pool Threads -> <reBleSum> 30 </ Threadsum> <!
Ce qui précède concerne cet article, j'espère qu'il sera utile à l'apprentissage de tout le monde.