JavaRush /Blog Java /Random-FR /Les classes Socket et ServerSocket, ou « Bonjour serveur ...
Sergey Simonov
Niveau 36
Санкт-Петербург

Les classes Socket et ServerSocket, ou « Bonjour serveur ? Pouvez-vous m'entendre?"

Publié dans le groupe Random-FR
Introduction : « Il y avait un ordinateur sur la table, derrière lui il y avait un encodeur... » Il était Les classes Socket et ServerSocket, ou « Bonjour serveur ?  Pouvez-vous m'entendre?"  - 1 une fois un de mes camarades de classe qui publiait un autre résultat de son étude de Java, sous la forme d'une capture d'écran d'un nouveau programme. Ce programme était un chat multi-utilisateurs. À cette époque, je commençais tout juste mon propre parcours de maîtrise de la programmation dans ce langage, mais je me suis définitivement dit : « Je le veux ! Le temps a passé et, après avoir fini de travailler sur le prochain projet dans le cadre de l'approfondissement de mes connaissances en programmation, je me suis souvenu de cet incident et j'ai décidé qu'il était temps. D'une manière ou d'une autre, j'ai déjà commencé à approfondir ce sujet par pure curiosité, mais dans mon manuel Java principal (c'était le manuel complet de Schildt), seules 20 pages étaient fournies pour le package java.net. C'est compréhensible - le livre est déjà très volumineux. Il y avait des tableaux de méthodes et de constructeurs des classes principales, mais c'est tout. La prochaine étape est, bien sûr, le tout-puissant Google : des myriades d'articles divers où la même chose est présentée - deux ou trois mots sur les sockets, et un exemple tout fait. L'approche classique (du moins dans mon style d'étude) consiste d'abord à comprendre de quels outils j'ai besoin pour travailler, ce qu'ils sont, pourquoi ils sont nécessaires, et ensuite seulement, si la solution au problème n'est pas évidente, à bricoler les outils prêts à l'emploi. -faites des listings, en dévissant les écrous et les boulons. Mais j'ai compris de quoi il s'agissait et j'ai finalement écrit un chat multi-utilisateurs. Extérieurement, cela s'est avéré quelque chose comme ceci : Les classes Socket et ServerSocket, ou « Bonjour serveur ?  Pouvez-vous m'entendre?"  - 2ici, je vais essayer de vous faire comprendre les bases des applications client-serveur basées sur des sockets Java en utilisant l'exemple de la conception de chat. Dans le cours Javarash, vous discuterez. Ce sera à un tout autre niveau, beau, grand, multifonctionnel. Mais avant tout, il faut toujours jeter les bases, nous devons donc ici comprendre ce qui sous-tend une telle section. (Si vous constatez des lacunes ou des erreurs, écrivez-le en MP ou en commentaire sous l'article). Commençons. Premier titre : « La maison qui... » Pour expliquer comment se produit une connexion réseau entre un serveur et un client, prenons l'exemple désormais classique d'un immeuble d'habitation. Disons qu'un client doit établir d'une manière ou d'une autre une connexion avec un serveur spécifique. Que doit savoir le chercheur sur l’objet recherché ? Oui, l'adresse. Le serveur n’est pas une entité magique sur le cloud, et il doit donc être localisé sur une machine spécifique. Par analogie avec une maison, où devrait avoir lieu une réunion de deux parties convenues. Et pour se retrouver dans un immeuble à appartements, une seule adresse de l'immeuble ne suffit pas, il faut indiquer le numéro de l'appartement dans lequel aura lieu la rencontre. De même, sur un ordinateur, il peut y avoir plusieurs serveurs à la fois, et pour que le client puisse en contacter un en particulier, il doit également spécifier le numéro de port via lequel la connexion se fera. Donc, l'adresse et le numéro de port. Une adresse désigne un identifiant de machine dans l'espace Internet. Il peut s'agir d'un nom de domaine, par exemple "javarush.ru" , ou d'une adresse IP ordinaire. Port- un numéro unique auquel une socket spécifique est associée (ce terme sera abordé plus loin), c'est-à-dire qu'il est occupé par un certain service afin qu'il puisse être utilisé pour le contacter. Ainsi, pour qu'au moins deux objets se rencontrent sur le territoire de l'un (serveur), le propriétaire de la zone (serveur) doit y occuper un appartement (port) spécifique (voiture), et le second doit trouver le lieu de rendez-vous sachant l'adresse de la maison (domaine ou ip) et le numéro de l'appartement (port). Deuxième tête : découvrez Socket Parmi les concepts et termes liés au travail sur le réseau, un très important est Socket. Il désigne le point par lequel la connexion se produit. En termes simples, un socket connecte deux programmes sur un réseau. La classe Socketimplémente l'idée d'un socket. Le client et le serveur communiqueront via ses canaux d'entrée/sortie : Les classes Socket et ServerSocket, ou « Bonjour serveur ?  Pouvez-vous m'entendre?"  - 3 Cette classe est déclarée côté client, et le serveur la recrée en recevant un signal de connexion. C’est ainsi que fonctionne la communication en ligne. Pour commencer, voici les constructeurs de classes possibles Socket:
Socket(String Name_хоста, int порт) throws UnknownHostException, IOException
Socket(InetAddress IP-address, int порт) throws UnknownHostException
"host_name" - implique un nœud de réseau spécifique, une adresse IP. Si la classe socket ne parvient pas à la convertir en une adresse réelle existante, une exception sera levée UnknownHostException. Le port est un port. Si 0 est spécifié comme numéro de port, le système lui-même attribuera un port libre. Une exception peut également se produire si la connexion est perdue IOException. Il convient de noter que le type d'adresse dans le deuxième constructeur est InetAddress. Cela vient à votre secours, par exemple, lorsque vous devez spécifier un nom de domaine comme adresse. De plus, lorsqu'un domaine implique plusieurs adresses IP, InetAddressvous pouvez les utiliser pour en obtenir un tableau. Cependant, cela fonctionne également avec IP. Vous pouvez également obtenir le nom d'hôte, le tableau d'octets qui constitue l'adresse IP, etc. Nous y reviendrons un peu plus loin, mais vous devrez vous rendre à la documentation officielle pour plus de détails. Lorsqu'un objet de type est initialisé Socket, le client auquel il appartient annonce sur le réseau qu'il souhaite se connecter au serveur à une adresse et un numéro de port précis. Voici les méthodes de la classe les plus fréquemment utilisées Socket: InetAddress getInetAddress()– renvoie un objet contenant des données sur le socket. Si le socket n'est pas connecté - null int getPort()- renvoie le port sur lequel la connexion au serveur s'effectue int getLocalPort()- renvoie le port auquel le socket est lié. Le fait est que le client et le serveur peuvent « communiquer » sur un port, mais les ports auxquels ils sont liés peuvent être complètement différents boolean isConnected()- renvoie vrai si la connexion est établie void connect(SocketAddress address)- indique une nouvelle connexion boolean isClosed()- renvoie vrai si le socket est fermé boolean isBound()- renvoie true, si le socket est réellement lié à une adresse, la classe Socketimplémente l'interface AutoCloseable, elle peut donc être utilisée dans le try-with-resources. Cependant, vous pouvez également fermer un socket de manière classique, en utilisant close(). Troisième tête : et ceci est un ServerSocket Disons que nous avons déclaré, sous la forme d'une classe Socket, une demande de connexion côté client. Comment le serveur va-t-il deviner notre souhait ? Pour cela, le serveur a une classe comme ServerSocket, et la méthode accept() dedans. Ses constructeurs sont présentés ci-dessous :
ServerSocket() throws IOException
ServerSocket(int порт) throws IOException
ServerSocket(int порт, int максимум_подключений) throws IOException
ServerSocket(int порт, int максимум_подключений, InetAddress локальный_address) throws IOException
Lors de la déclaration, ServerSocket vous n'avez pas besoin de préciser l'adresse de connexion, car la communication s'effectue sur la machine serveur. Uniquement avec un hôte multicanal, vous devez spécifier à quelle adresse IP le socket du serveur est lié. Troisième tête. Un : le serveur qui dit non Puisque fournir à un programme plus de ressources que ce dont il a besoin est à la fois coûteux et déraisonnable, il ServerSocketvous est donc demandé dans le constructeur de déclarer le nombre maximum de connexions acceptées par le serveur pendant son fonctionnement. S'il n'est pas précisé, alors par défaut ce nombre sera considéré comme égal à 50. Oui, en théorie on peut supposer qu'il ServerSockets'agit du même socket, uniquement pour le serveur. Mais elle joue un rôle complètement différent de celui de la classe Socket. Il n'est nécessaire qu'au stade de la création de la connexion. Après avoir créé un objet type, ServerSocketvous devez découvrir que quelqu'un souhaite se connecter au serveur. La méthode accept() est connectée ici. La cible attend que quelqu'un veuille s'y connecter, et lorsque cela se produit, elle renvoie un objet de type Socket, c'est-à-dire un socket client recréé. Et maintenant que le socket client a été créé côté serveur, la communication bidirectionnelle peut commencer. Créer un objet type Socketcôté client et le recréer ServerSocketcôté serveur est le minimum requis pour la connexion. Quatrième titre : Lettre au Père Noël Вопрос: Comment exactement le client et le serveur communiquent-ils ? Ответ:Via les flux d'E/S. Qu'avons-nous déjà ? Un socket avec l’adresse du serveur et le numéro de port du client, et pareil, grâce à accept(), côté serveur. Il est donc raisonnable de supposer qu’ils communiqueront via un socket. Pour ce faire, il existe deux méthodes qui donnent accès aux flux InputStreamet OutputStreamobjets de type Socket. Les voici:
InputStream getInputStream()
OutputStream getOutputStream()
Étant donné que la lecture et l’écriture d’octets nus ne sont pas aussi efficaces, les flux peuvent être encapsulés dans des classes d’adaptateur, mis en mémoire tampon ou non. Par exemple:
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
Pour que la communication soit bidirectionnelle, ces opérations doivent être effectuées des deux côtés. Vous pouvez désormais envoyer quelque chose en utilisant et recevoir quelque chose en utilisant, et vice versa. En fait, c'est pratiquement la seule fonction de la classe Socket. Et oui, n'oubliez pas la méthode flush() BufferedWriter- elle vide le contenu du tampon. Si cela n’est pas fait, les informations ne seront pas transmises et ne seront donc pas reçues. Le thread de réception attend également l'indicateur de fin de ligne – « \n », sinon le message ne sera pas accepté, car en fait le message n'est pas terminé et n'est pas complet. Si cela vous semble gênant, ne vous inquiétez pas, vous pouvez toujours utiliser la classe PrintWriter, qui doit être bouclée, spécifier true comme deuxième argument, puis l'extraction du tampon se fera automatiquement :
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
De plus, il n’est pas nécessaire d’indiquer la fin de la ligne ; cette classe le fait pour vous. Mais les E/S de chaîne sont-elles la limite de ce qu'un socket peut faire ? Non, voulez-vous envoyer des objets via des flux de socket ? Pour l'amour de Dieu. Sérialisez-les et vous êtes prêt à partir :
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
Cinquième chapitre : une vraie communication via Internet Puisque pour se connecter via un vrai réseau avec une vraie adresse IP, il faut disposer d'un serveur à part entière, et puisque :
  1. Notre futur chat, en tant qu'utilitaire, n'a pas de telles capacités. Il peut uniquement établir une connexion et recevoir/envoyer un message. Autrement dit, il ne dispose pas de véritables capacités de serveur.
  2. Notre serveur, contenant uniquement des données de socket et des flux d'E/S, ne peut pas fonctionner comme un véritable serveur WEB ou FTP, donc avec seulement cela nous ne pourrons pas nous connecter sur Internet.
Et en plus, nous commençons tout juste à développer le programme, ce qui signifie qu'il n'est pas assez stable pour fonctionner immédiatement avec un réseau réel, nous utiliserons donc l'hôte local comme adresse de connexion. Autrement dit, en théorie, le client et le serveur ne seront toujours connectés que via un socket, mais pour déboguer le programme, ils seront sur la même machine, sans réel contact sur le réseau. Afin d'indiquer dans le constructeur Socketque l'adresse est locale, il existe 2 manières :
  1. Écrivez « localhost » comme argument d'adresse, ce qui signifie un stub local. "127.0.0.1" convient également à cela - il s'agit simplement d'une forme numérique d'un talon.
  2. Utilisation d'InetAddress :
    1. InetAddress.getByName(null)- null pointe vers localhost
    2. InetAddress.getByName("localhost")
    3. InetAddress.getByName("127.0.0.1")
Pour plus de simplicité, nous utiliserons « localhost » de type String. Mais toutes les autres options sont également réalisables. Tête six : Il est temps d'avoir une conversation. Nous avons donc déjà tout ce dont nous avons besoin pour mettre en œuvre une session de conversation avec le serveur. Il ne reste plus qu'à l'assembler : le listing suivant montre comment le client se connecte au serveur, lui envoie un message et le serveur, à son tour, confirme qu'il a reçu le message en l'utilisant comme argument dans son : "Serveur. Java"
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {

    private static Socket clientSocket; // socket for communication
    private static ServerSocket server; // server socket
    private static BufferedReader in; // socket read stream
    private static BufferedWriter out; // socket write stream

    public static void main(String[] args) {
        try {
            try  {
                server = new ServerSocket(4004); // server socket listening on port 4004
                System.out.println("Server is running!"); // server would be nice
                // announce your launch
                clientSocket = server.accept(); // accept() will wait until
                //someone won't want to connect
                try { // after establishing a connection and recreating the socket for communication with the client, you can go
                    // to create I/O streams.
                    // now we can receive messages
                    in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                    // and send
                    out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

                    String word = in.readLine(); // wait for the client to write something to us
                    System.out.println(word);
                    // without hesitation responds to the client
                    out.write("Hi, this is the Server! I confirm you wrote: " + word + "\n");
                    out.flush(); // push everything out of the buffer

                } finally { // in any case, the socket will be closed
                    clientSocket.close();
                    // streams would also be nice to close
                    in.close();
                    out.close();
                }
            } finally {
                System.out.println("Server closed!");
                    server.close();
            }
        } catch (IOException e) {
            System.err.println(e);
        }
    }
"Client.java"
import java.io.*;
import java.net.Socket;

public class Client {

    private static Socket clientSocket; // socket for communication
    private static BufferedReader reader; // we need a reader that reads from the console, otherwise
    // do we know what the client wants to say?
    private static BufferedReader in; // socket read stream
    private static BufferedWriter out; // socket write stream

    public static void main(String[] args) {
        try {
            try {
                // address - local host, port - 4004, same as the server
                clientSocket = new Socket("localhost", 4004); // with this line we request
                // the server has access to the connection
                reader = new BufferedReader(new InputStreamReader(System.in));
                // read messages from the server
                in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
                // write there
                out = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream()));

                System.out.println("Did you have something to say? Enter it here:");
                // if the connection happened and the threads were successfully created - we can
                // work further and offer the client something to enter
                // if not, an exception will be thrown
                String word = reader.readLine(); // wait for the client to do something
                // will not write to the console
                out.write(word + "\n"); // send a message to the server
                out.flush();
                String serverWord = in.readLine(); // wait for the server to say
                System.out.println(serverWord); // received - display
            } finally { // in any case, you need to close the socket and streams
                System.out.println("The client has been closed...");
                clientSocket.close();
                in.close();
                out.close();
            }
        } catch (IOException e) {
            System.err.println(e);
        }

    }
}
Bien sûr, vous devez d’abord démarrer le serveur, car à quoi le client se connectera-t-il au démarrage s’il n’y a rien qui le connecte ? :) Le résultat sera comme ceci : /* Vouliez-vous dire quelque chose ? Entrez-le ici : Bonjour, serveur ? Pouvez-vous m'entendre? Bonjour, c'est le serveur ! Je confirme, vous avez écrit : Bonjour, serveur ? Pouvez-vous m'entendre? Le client était fermé... */ Hourra ! Nous avons appris au serveur à communiquer avec le client ! Pour que la communication ne se fasse pas en deux répliques, mais en autant de répliques que vous le souhaitez, enveloppez simplement la lecture et l'écriture des threads dans une boucle while (true) et indiquez pour la sortie que, selon un certain message, par exemple, « exit » , le cycle était interrompu et le programme se terminait. Head Seven : Le multi-utilisateur, c'est mieux. Le fait que le serveur puisse nous entendre est une bonne chose, mais ce serait bien mieux si nous pouvions communiquer avec quelqu'un de notre espèce. Je joindrai toutes les sources en fin d'article, je montrerai donc ici des morceaux de code pas toujours volumineux, mais importants qui permettront, s'ils sont utilisés correctement, de concocter un chat multi-utilisateurs. Nous voulons donc pouvoir communiquer avec un autre client via le serveur. Comment faire? Évidemment, puisque le programme client a sa propre méthode main, cela signifie qu'il peut être lancé séparément du serveur et en parallèle avec d'autres clients. Qu'est-ce que cela nous donne ? D'une manière ou d'une autre, il est nécessaire qu'à chaque nouvelle connexion, le serveur ne passe pas immédiatement en communication, mais écrive cette connexion dans une sorte de liste et attende une nouvelle connexion, et une sorte de service auxiliaire soit engagé dans la communication avec un spécifique client. Et les clients doivent écrire sur le serveur et attendre une réponse indépendamment les uns des autres. Les fils viennent à la rescousse. Disons que nous avons une classe chargée de mémoriser les nouvelles connexions : elle doit spécifier les éléments suivants :
  1. Numéro de port.
  2. La liste dans laquelle il écrit la nouvelle connexion.
  3. Et ServerSocket, en un seul (!) exemplaire.
public class Server {

    public static final int PORT = 8080;
    public static LinkedList<ServerSomthing> serverList = new LinkedList<>(); // list of all threads

    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(PORT);
            try {
            while (true) {
                // Blocks until a new connection is made:
                Socket socket = server.accept();
                try {
                    serverList.add(new ServerSomthing(socket)); // add a new connection to the list
                } catch (IOException e) {
                    // If it fails, the socket is closed,
                    // otherwise, the thread will close it when it exits:
                    socket.close();
                }
            }
        } finally {
            server.close();
        }
    }
}
D'accord, désormais chaque socket recréée ne sera pas perdue, mais sera stockée sur le serveur. Plus loin. Chaque client a besoin de quelqu'un pour l'écouter. Créons un fil de discussion avec les fonctions serveur du dernier chapitre.
class ServerSomthing extends Thread {

    private Socket socket; // socket through which the server communicates with the client,
    // except for it - the client and server are not connected in any way
    private BufferedReader in; // socket read stream
    private BufferedWriter out; // socket write stream

    public ServerSomthing(Socket socket) throws IOException {
        this.socket = socket;
        // если потоку ввода/вывода приведут к генерированию исключения, оно пробросится дальше
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        start(); // call run()
    }
    @Override
    public void run() {
        String word;
        try {

            while (true) {
                word = in.readLine();
                if(word.equals("stop")) {
                    break;                }
                for (ServerSomthing vr : Server.serverList) {
                    vr.send(word); // send the received message with
                   // bound client to everyone else including him
                }
            }

        } catch (IOException e) {
        }
    }

    private void send(String msg) {
        try {
            out.write(msg + "\n");
            out.flush();
        } catch (IOException ignored) {}
    }
}
Ainsi, dans le constructeur du thread serveur, un socket doit être initialisé à travers lequel le thread communiquera avec un client spécifique. Également les threads d'E/S et tout ce dont vous avez besoin pour démarrer un thread directement à partir du constructeur. D'accord, mais que se passe-t-il lorsque le thread du serveur lit un message du client ? Renvoyer uniquement à votre client ? Pas très efficace. Nous créons un chat multi-utilisateurs, nous avons donc besoin que chaque client connecté reçoive ce qu'une personne a écrit. Vous devez utiliser la liste de tous les threads du serveur associés à leurs clients et envoyer chaque message envoyé à un thread spécifique pour qu'il l'envoie à son client :
for (ServerSomthing vr : Server.serverList) {
    vr.send(word); // send the received message
    // from the linked client to everyone else, including him
}
private void send(String msg) {
    try {
        out.write(msg + "\n");
        out.flush();
    } catch (IOException ignored) {}
}
Désormais, tous les clients sauront ce que l’un d’eux a dit ! Si vous ne souhaitez pas que le message soit envoyé à celui qui l'a envoyé (il sait déjà ce qu'il a écrit !), simplement lors de l'itération dans les threads, précisez que lors du traitement d'un objet, la thisboucle passera à l'élément suivant sans effectuer toute action à ce sujet. Ou, si vous préférez, envoyez un message au client indiquant que le message a été reçu et envoyé avec succès. Tout est désormais clair avec le serveur. Passons au client, ou plutôt aux clients ! Tout y est pareil, par analogie avec le client du chapitre dernier, uniquement lors de la création d'une instance, il faut, comme cela a été montré dans ce chapitre avec le serveur, créer tout le nécessaire dans le constructeur. Mais que se passe-t-il si, lors de la création d'un client, il n'a pas encore eu le temps de saisir quoi que ce soit, mais que quelque chose lui a déjà été envoyé ? (Par exemple, l'historique des correspondances de ceux qui se sont déjà connectés au chat avant lui). Ainsi, les cycles dans lesquels les messages envoyés seront traités doivent être séparés de ceux dans lesquels les messages sont lus depuis la console et envoyés au serveur pour être transmis à d'autres. Les fils viennent à nouveau à la rescousse. Cela ne sert à rien de créer un client en tant que thread. Il est plus pratique de créer un thread avec une boucle dans la méthode run qui lit les messages et, par analogie, écrit également :
// thread reading messages from the server
private class ReadMsg extends Thread {
    @Override
    public void run() {

        String str;
        try {
            while (true) {
                str = in.readLine(); // waiting for a message from the server
                if (str.equals("stop")) {

                    break; // exit the loop if it's "stop"
                }
                            }
        } catch (IOException e) {

        }
    }
}
// thread sending messages coming from the console to the server
public class WriteMsg extends Thread {

    @Override
    public void run() {
        while (true) {
            String userWord;
            try {
               userWord = inputUser.readLine(); // messages from the console
                if (userWord.equals("stop")) {
                    out.write("stop" + "\n");
                    break; // exit the loop if it's "stop"
                } else {
                    out.write(userWord + "\n"); // send to the server
                }
                out.flush(); // clean up
            } catch (IOException e) {

            }

        }
    }
}
Dans le constructeur client, il vous suffit de démarrer ces threads. Comment bien clôturer les ressources d’un client s’il souhaite partir ? Dois-je fermer les ressources du thread du serveur ? Pour ce faire, vous devrez probablement créer une méthode distincte qui sera appelée lors de la sortie de la boucle de messages. Là, vous devrez fermer le socket et les flux d’E/S. Le même signal de fin de session pour un client particulier doit être envoyé à son thread serveur, qui doit faire de même avec son socket et se supprimer de la liste des threads de la classe serveur principale. Head Eight : Il n'y a pas de limite à la perfection Vous pouvez inventer à l'infini de nouvelles fonctionnalités pour améliorer votre projet. Mais que faut-il exactement transférer à un client nouvellement connecté ? Je pense que les dix derniers événements se sont produits avant son arrivée. Pour ce faire, vous devez créer une classe dans laquelle la dernière action avec n'importe quel thread du serveur sera inscrite dans la liste déclarée, et si la liste est déjà pleine (c'est-à-dire qu'il y en a déjà 10), supprimez la première et ajoutez le dernier qui est venu. Pour que le contenu de cette liste soit reçu par une nouvelle connexion, lors de la création d'un thread serveur, dans le flux de sortie, vous devez les envoyer au client. Comment faire? Par exemple, comme ceci :
public void printStory(BufferedWriter writer) {
// ...
}
Le thread du serveur a déjà créé des flux et peut transmettre le flux de sortie comme argument. Ensuite, il vous suffit de transmettre tout ce qui doit être transféré au nouveau client lors d'un cycle de recherche. Conclusion : ce ne sont que les bases, et très probablement cette architecture de chat ne fonctionnera pas lors de la création d'une véritable application. Ce programme a été créé à des fins pédagogiques et sur cette base j'ai montré comment faire communiquer le client avec le serveur (et vice versa), comment le faire pour plusieurs connexions et, bien sûr, comment cela est organisé sur les sockets. Les sources sont réorganisées ci-dessous et le code source du programme analysé est également joint. C'est ma première expérience d'écriture d'un article) Merci de votre attention :)
  1. Penser en Java Enterprise, par Bruce Eckel et. Al. 2003
  2. Java 8, The Complete Guide, Herbert Schildt, 9e édition, 2017 (Chapitre 22)
  3. Article sur la programmation des sockets en Java sur les sockets
  4. Prise dans la documentation officielle
  5. ServerSocket dans la documentation officielle
  6. sources sur GitHub
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION