Comment créer une application réseau en Java (avec des images)

Table des matières:

Comment créer une application réseau en Java (avec des images)
Comment créer une application réseau en Java (avec des images)

Vidéo: Comment créer une application réseau en Java (avec des images)

Vidéo: Comment créer une application réseau en Java (avec des images)
Vidéo: Comment enregistrer l'écran de son smartphone sur Android ? Notre tuto 2024, Peut
Anonim

Écrire du code qui s'exécute sur un certain appareil est très satisfaisant. Mais, écrire du code qui s'exécute sur plusieurs appareils qui communiquent entre eux est tout simplement une affirmation de vie. Cet article vous apprendra comment vous connecter et échanger des messages sur le réseau à l'aide du protocole de contrôle de transmission (TCP).

Dans cet article, vous allez configurer une application qui connectera votre ordinateur à lui-même et, essentiellement, le rendra fou - parler à lui-même. Vous apprendrez également la différence entre les deux flux les plus utilisés pour la mise en réseau en Java et leur fonctionnement.

Flux de données et d'objets

Avant de plonger dans le code, il faut distinguer la différence entre les deux flux utilisés dans l'article.

Flux de données

Les flux de données traitent les types de données et les chaînes primitifs. Les données envoyées via des flux de données doivent être sérialisées et désérialisées manuellement, ce qui rend plus difficile le transfert de données complexes. Mais, les flux de données peuvent communiquer avec des serveurs et des clients écrits dans d'autres langages que Java. Les flux bruts sont similaires aux flux de données dans cet aspect, mais les flux de données garantissent que les données sont formatées d'une manière indépendante de la plate-forme, ce qui est avantageux car les deux parties pourront lire les données envoyées.

Flux d'objets

Les flux d'objets traitent les types de données primitifs et les objets qui implémentent

Sérialisable

interface. Les données envoyées sur les flux d'objets sont automatiquement sérialisées et désérialisées, ce qui facilite le transfert de données complexes. Mais, les flux d'objets ne peuvent communiquer qu'avec des serveurs et des clients écrits en Java. Aussi,

ObjectOutputStream

lors de l'initialisation, envoie un en-tête au

Flux d'entrée

de l'autre partie qui, lors de l'initialisation, bloque l'exécution jusqu'à la réception de l'en-tête.

Pas

Créer une application réseau en Java Step1
Créer une application réseau en Java Step1

Étape 1. Créez une classe

Créez une classe et nommez-la comme vous le souhaitez. Dans cet article, il sera nommé

Exemple d'application de réseau

classe publique NetworkAppExample { }

Créer une application réseau en Java Step2
Créer une application réseau en Java Step2

Étape 2. Créez une méthode principale

Créer une méthode principale et la déclarer pourrait lever des exceptions de

Exception

type et toute sous-classe de celui-ci - toutes les exceptions. Ceci est considéré comme une mauvaise pratique, mais est acceptable pour des exemples simples.

public class NetworkAppExample { public static void main(String args) lève une exception { } }

Créer une application réseau en Java Step3
Créer une application réseau en Java Step3

Étape 3. Déclarez l'adresse du serveur

Cet exemple utilisera l'adresse de l'hôte local et un numéro de port arbitraire. Le numéro de port doit être compris entre 0 et 65535 (inclus). Cependant, les numéros de port à éviter vont de 0 à 1023 (inclus) car ce sont des ports système réservés.

public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; } }

Créer une application réseau en Java Step4
Créer une application réseau en Java Step4

Étape 4. Créez un serveur

Le serveur est lié à l'adresse et au port et écoute les connexions entrantes. A Java,

ServerSocket

représente le point de terminaison côté serveur et sa fonction accepte de nouvelles connexions.

ServerSocket

n'a pas de flux pour la lecture et l'envoi de données car il ne représente pas la connexion entre un serveur et un client.

importer java.net. InetAddress; importer java.net. ServerSocket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); } }

Créer une application réseau en Java Step5
Créer une application réseau en Java Step5

Étape 5. Création du serveur de journal

À des fins de journalisation, imprimez sur la console que le serveur a été démarré.

importer java.net. InetAddress; importer java.net. ServerSocket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); } }

Créer une application réseau en Java Step6
Créer une application réseau en Java Step6

Étape 6. Créez un client

Le client est lié à l'adresse et au port d'un serveur et écoute les paquets (messages) une fois la connexion établie. A Java,

Prise

représente soit un point de terminaison côté client connecté au serveur, soit une connexion (du serveur) au client et est utilisé pour communiquer avec la partie à l'autre extrémité.

importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); } }

Créer une application réseau en Java Step7
Créer une application réseau en Java Step7

Étape 7. Tentative de connexion de journal

À des fins de journalisation, imprimez sur la console que la connexion a été tentée.

importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); } }

Créer une application réseau en Java Step8
Créer une application réseau en Java Step8

Étape 8. Établir la connexion

Les clients ne se connecteront jamais à moins que le serveur n'écoute et n'accepte, en d'autres termes n'établisse, les connexions. En Java, les connexions sont établies en utilisant

J'accepte()

méthode de

ServerSocket

classer. La méthode bloquera l'exécution jusqu'à ce qu'un client se connecte.

importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); } }

Créer une application réseau en Java Step9
Créer une application réseau en Java Step9

Étape 9. Connectez-vous à la connexion établie

À des fins de journalisation, imprimez sur la console que la connexion entre le serveur et le client a été établie.

importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); } }

Créer une application réseau en Java Step10
Créer une application réseau en Java Step10

Étape 10. Préparez les flux de communication

La communication s'effectue via des flux et, dans cette application, les flux bruts de (connexion depuis) le serveur (vers le client) et le client doivent être enchaînés à des flux de données ou d'objets. N'oubliez pas que les deux parties doivent utiliser le même type de flux.

  • Flux de données

    importer java.io. DataInputStream; importer java.io. DataOutputStream; importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); DataOutputStream clientOut = new DataOutputStream(client.getOutputStream()); DataInputStream clientIn = new DataInputStream(client.getInputStream()); DataOutputStream serverOut = new DataOutputStream(connection.getOutputStream()); DataInputStream serverIn = new DataInputStream(connection.getInputStream()); } }

  • Flux d'objets

    Lorsque plusieurs flux d'objets sont utilisés, les flux d'entrée doivent être initialisés dans le même ordre que les flux de sortie car

    ObjectOutputStream

    envoie un en-tête à l'autre partie et

    ObjectInputStream

    bloque l'exécution jusqu'à ce qu'il lise l'en-tête.

    importer java.io. ObjectInputStream; importer java.io. ObjectOutputStream; importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); ObjectOutputStream clientOut = new ObjectOutputStream(client.getOutputStream()); ObjectOutputStream serverOut = new ObjectOutputStream(connection.getOutputStream()); ObjectInputStream clientIn = new ObjectInputStream(client.getInputStream()); ObjectInputStream serverIn = new ObjectInputStream(connection.getInputStream()); } }

    L'ordre tel que spécifié dans le code ci-dessus peut être plus facile à retenir - initialisez d'abord les flux de sortie, puis les flux d'entrée dans le même ordre. Cependant, un autre ordre d'initialisation des flux d'objets est le suivant:

    ObjectOutputStream clientOut = new ObjectOutputStream(client.getOutputStream()); ObjectInputStream serverIn = new ObjectInputStream(connection.getInputStream()); ObjectOutputStream serverOut = new ObjectOutputStream(connection.getOutputStream()); ObjectInputStream clientIn = new ObjectInputStream(client.getInputStream());

Créer une application réseau en Java Step11
Créer une application réseau en Java Step11

Étape 11. Consignez que la communication est prête

À des fins de journalisation, imprimez sur la console que la communication est prête.

// code omis import java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); // code omis System.out.println("La communication est prête."); } }

Créer une application réseau en Java Step12
Créer une application réseau en Java Step12

Étape 12. Créez un message

Dans cette application,

Bonjour le monde

le texte sera envoyé au serveur soit comme

octet

ou

Chaîne de caractères

. Déclarez une variable du type qui dépend du flux utilisé. Utilisation

octet

pour les flux de données et

Chaîne de caractères

pour les flux d'objets.

  • Flux de données

    À l'aide de flux de données, la sérialisation est effectuée en convertissant les objets en types de données primitifs ou en un

    Chaîne de caractères

    . Dans ce cas,

    Chaîne de caractères

    est converti en

    octet

    au lieu d'écrire en utilisant

    écrireOctets()

    méthode pour montrer comment cela serait fait avec d'autres objets, tels que des images ou d'autres fichiers.

    importer java.io. DataInputStream; importer java.io. DataOutputStream; importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); DataOutputStream clientOut = new DataOutputStream(client.getOutputStream()); DataInputStream clientIn = new DataInputStream(client.getInputStream()); DataOutputStream serverOut = new DataOutputStream(connection.getOutputStream()); DataInputStream serverIn = new DataInputStream(connection.getInputStream()); System.out.println("La communication est prête."); byte messageOut = "Hello World".getBytes(); } }

  • Flux d'objets

    importer java.io. ObjectInputStream; importer java.io. ObjectOutputStream; importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); ObjectOutputStream clientOut = new ObjectOutputStream(client.getOutputStream()); ObjectOutputStream serverOut = new ObjectOutputStream(connection.getOutputStream()); ObjectInputStream clientIn = new ObjectInputStream(client.getInputStream()); ObjectInputStream serverIn = new ObjectInputStream(connection.getInputStream()); System.out.println("La communication est prête."); String messageOut = "Bonjour tout le monde"; } }

Créer une application réseau en Java Step13
Créer une application réseau en Java Step13

Étape 13. Envoyez le message

Écrivez les données dans le flux de sortie et videz le flux pour vous assurer que les données ont été entièrement écrites.

  • Flux de données

    La longueur d'un message doit être envoyée en premier afin que l'autre partie sache combien d'octets il doit lire. Une fois la longueur envoyée en tant que type entier primitif, des octets peuvent être envoyés.

    importer java.io. DataInputStream; importer java.io. DataOutputStream; importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); DataOutputStream clientOut = new DataOutputStream(client.getOutputStream()); DataInputStream clientIn = new DataInputStream(client.getInputStream()); DataOutputStream serverOut = new DataOutputStream(connection.getOutputStream()); DataInputStream serverIn = new DataInputStream(connection.getInputStream()); System.out.println("La communication est prête."); byte messageOut = "Hello World".getBytes(); clientOut.writeInt(messageOut.length); clientOut.write(messageOut); clientOut.flush(); } }

  • Flux d'objets

    importer java.io. ObjectInputStream; importer java.io. ObjectOutputStream; importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); ObjectOutputStream clientOut = new ObjectOutputStream(client.getOutputStream()); ObjectOutputStream serverOut = new ObjectOutputStream(connection.getOutputStream()); ObjectInputStream clientIn = new ObjectInputStream(client.getInputStream()); ObjectInputStream serverIn = new ObjectInputStream(connection.getInputStream()); System.out.println("La communication est prête."); String messageOut = "Bonjour tout le monde"; clientOut.writeObject(messageOut); clientOut.flush(); } }

Créer une application réseau en Java Step14
Créer une application réseau en Java Step14

Étape 14. Message envoyé par journal

À des fins de journalisation, imprimez sur la console que le message a été envoyé.

  • Flux de données

    importer java.io. DataInputStream; importer java.io. DataOutputStream; importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); DataOutputStream clientOut = new DataOutputStream(client.getOutputStream()); DataInputStream clientIn = new DataInputStream(client.getInputStream()); DataOutputStream serverOut = new DataOutputStream(connection.getOutputStream()); DataInputStream serverIn = new DataInputStream(connection.getInputStream()); System.out.println("La communication est prête."); byte messageOut = "Hello World".getBytes(); clientOut.writeInt(messageOut.length); clientOut.write(messageOut); clientOut.flush(); System.out.println("Message envoyé au serveur: " + new String(messageOut)); } }

  • Flux d'objets

    importer java.io. ObjectInputStream; importer java.io. ObjectOutputStream; importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); ObjectOutputStream clientOut = new ObjectOutputStream(client.getOutputStream()); ObjectOutputStream serverOut = new ObjectOutputStream(connection.getOutputStream()); ObjectInputStream clientIn = new ObjectInputStream(client.getInputStream()); ObjectInputStream serverIn = new ObjectInputStream(connection.getInputStream()); System.out.println("La communication est prête."); String messageOut = "Bonjour tout le monde"; clientOut.writeObject(messageOut); clientOut.flush(); System.out.println("Message envoyé au serveur: " + messageOut); } }

Créer une application réseau en Java Step15
Créer une application réseau en Java Step15

Étape 15. Lisez le message

Lire les données du flux d'entrée et les convertir. Puisque nous connaissons exactement le type de données envoyées, nous allons soit créer un

Chaîne de caractères

de

octet

ou coulé

Objet

à

Chaîne de caractères

sans vérification, selon le flux utilisé.

  • Flux de données

    Comme la longueur a été envoyée en premier et les octets ensuite, la lecture doit être effectuée dans le même ordre. Si la longueur est nulle, il n'y a rien à lire. L'objet est désérialisé lorsque les octets sont reconvertis en une instance, dans ce cas, de

    Chaîne de caractères

    importer java.io. DataInputStream; importer java.io. DataOutputStream; importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); DataOutputStream clientOut = new DataOutputStream(client.getOutputStream()); DataInputStream clientIn = new DataInputStream(client.getInputStream()); DataOutputStream serverOut = new DataOutputStream(connection.getOutputStream()); DataInputStream serverIn = new DataInputStream(connection.getInputStream()); System.out.println("La communication est prête."); byte messageOut = "Hello World".getBytes(); clientOut.writeInt(messageOut.length); clientOut.write(messageOut); clientOut.flush(); System.out.println("Message envoyé au serveur: " + new String(messageOut)); longueur int = serverIn.readInt(); if (longueur > 0) { octet messageIn = nouvel octet[longueur]; serverIn.readFully(messageIn, 0, messageIn.length); } } }

  • Flux d'objets

    importer java.io. ObjectInputStream; importer java.io. ObjectOutputStream; importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); ObjectOutputStream clientOut = new ObjectOutputStream(client.getOutputStream()); ObjectOutputStream serverOut = new ObjectOutputStream(connection.getOutputStream()); ObjectInputStream clientIn = new ObjectInputStream(client.getInputStream()); ObjectInputStream serverIn = new ObjectInputStream(connection.getInputStream()); System.out.println("La communication est prête."); String messageOut = "Bonjour tout le monde"; clientOut.writeObject(messageOut); clientOut.flush(); System.out.println("Message envoyé au serveur: " + messageOut); Chaîne messageIn = (chaîne) serverIn.readObject(); } }

Créer une application réseau en Java Step16
Créer une application réseau en Java Step16

Étape 16. Message de lecture de journal

À des fins de journalisation, imprimez sur la console que le message a été reçu et imprimez son contenu.

  • Flux de données

    importer java.io. DataInputStream; importer java.io. DataOutputStream; importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); DataOutputStream clientOut = new DataOutputStream(client.getOutputStream()); DataInputStream clientIn = new DataInputStream(client.getInputStream()); DataOutputStream serverOut = new DataOutputStream(connection.getOutputStream()); DataInputStream serverIn = new DataInputStream(connection.getInputStream()); System.out.println("La communication est prête."); byte messageOut = "Hello World".getBytes(); clientOut.writeInt(messageOut.length); clientOut.write(messageOut); clientOut.flush(); System.out.println("Message envoyé au serveur: " + new String(messageOut)); longueur int = serverIn.readInt(); if (longueur > 0) { octet messageIn = nouvel octet[longueur]; serverIn.readFully(messageIn, 0, messageIn.length); System.out.println("Message reçu du client: " + new String(messageIn)); } } }

  • Flux d'objets

    importer java.io. ObjectInputStream; importer java.io. ObjectOutputStream; importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); ObjectOutputStream clientOut = new ObjectOutputStream(client.getOutputStream()); ObjectOutputStream serverOut = new ObjectOutputStream(connection.getOutputStream()); ObjectInputStream clientIn = new ObjectInputStream(client.getInputStream()); ObjectInputStream serverIn = new ObjectInputStream(connection.getInputStream()); System.out.println("La communication est prête."); String messageOut = "Bonjour tout le monde"; clientOut.writeObject(messageOut); clientOut.flush(); System.out.println("Message envoyé au serveur: " + messageOut); Chaîne messageIn = (chaîne) serverIn.readObject(); System.out.println("Message reçu du client: " + messageIn); } }

Créer une application réseau en Java Step17
Créer une application réseau en Java Step17

Étape 17. Déconnectez les connexions

La connexion est interrompue lorsqu'une partie ferme ses flux. En Java, en fermant le flux de sortie, le socket et le flux d'entrée associés sont également fermés. Une fois qu'une partie à l'autre extrémité découvre que la connexion est morte, elle doit également fermer son flux de sortie pour éviter les fuites de mémoire.

// code omis import java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); // code omis System.out.println("La communication est prête."); // code omis clientOut.close(); serverOut.close(); } }

Créer une application réseau en Java Step18 V2
Créer une application réseau en Java Step18 V2

Étape 18. Déconnexion de journal

À des fins de journalisation, les connexions d'impression vers la console ont été déconnectées.

// code omis import java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); // code omis System.out.println("La communication est prête."); // code omis clientOut.close(); serverOut.close(); System.out.println("Connexions fermées."); } }

Créer une application réseau en Java Step19
Créer une application réseau en Java Step19

Étape 19. Terminez le serveur

Les connexions sont déconnectées, mais le serveur est toujours opérationnel. Comme

ServerSocket

n'est associé à aucun flux, il doit être explicitement fermé en appelant

proche()

méthode.

// code omis import java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); // code omis System.out.println("La communication est prête."); // code omis clientOut.close(); serverOut.close(); System.out.println("Connexions fermées."); serveur.close(); } }

Créer une application réseau en Java Step20
Créer une application réseau en Java Step20

Étape 20. Terminaison du serveur de journal

À des fins de journalisation, l'impression sur le serveur de console a été interrompue.

// code omis import java.net. InetAddress; importer java.net. ServerSocket; importer java.net. Socket; public class NetworkAppExample { public static void main(String args) lève une exception { String host = "localhost"; port int = 10430; ServerSocket server = new ServerSocket(port, 50, InetAddress.getByName(host)); System.out.println("Serveur démarré."); Client socket = nouveau Socket(hôte, port); System.out.println("Connexion au serveur…"); Connexion socket = server.accept(); System.out.println("Connexion établie."); // code omis System.out.println("La communication est prête."); // code omis clientOut.close(); serverOut.close(); System.out.println("Connexions fermées."); serveur.close(); System.out.println("Serveur arrêté."); } }

Créer une application réseau en Java Step21
Créer une application réseau en Java Step21

Étape 21. Compilez et exécutez

La journalisation nous a permis de savoir si l'application était réussie ou non. Production attendue:

Le serveur a démarré. Connexion au serveur… Connexion établie. La communication est prête. Message envoyé au serveur: Hello World Message reçu du client: Hello World Connections fermé. Serveur arrêté.

Si votre sortie ne ressemble pas à celle ci-dessus, ce qui est peu probable, il existe quelques solutions:

  • Si la sortie s'arrête à la ligne

    Connection établie.

    et les flux d'objets sont utilisés, videz chaque

    ObjectOutputStream

  • immédiatement après l'initialisation car les en-têtes, pour une raison quelconque, n'ont pas été envoyés.
  • Si la sortie imprime

    java.net. BindException: adresse déjà utilisée

  • choisissez un numéro de port différent car celui spécifié est déjà utilisé.

Des astuces

  • La connexion à un serveur sur un réseau différent se fait en se connectant à l'adresse IP externe d'un périphérique exécutant le serveur qui a un port transféré.
  • La connexion à un serveur sur le même réseau se fait soit en se connectant à l'adresse IP privée d'un appareil exécutant le serveur, soit en transférant un port et en se connectant à l'adresse IP externe de l'appareil.
  • Il existe des logiciels, tels que Hamachi, qui permettent de se connecter au serveur sur un réseau différent sans transférer de port, mais cela nécessite l'installation du logiciel sur les deux appareils.

Exemples

Les applications réseau qui utilisent des entrées/sorties bloquantes doivent utiliser des threads. Les exemples suivants montrent une implémentation serveur et client minimaliste avec des threads. Le code de mise en réseau est essentiellement le même que dans l'article, sauf que certains extraits ont été synchronisés, déplacés dans des threads et que les exceptions sont gérées.

Serveur.java

importer java.io. IOException; importer java.net. InetAddress; importer java.net. ServerSocket; importer java.net. SocketException; importer java.net. UnknownHostException; importer java.util. ArrayList; importer java.util. Collections; importer java.util. List; /** * La classe {@code Server} représente un point de terminaison de serveur dans un réseau. {@code Server} une fois lié à une certaine adresse IP * et à un certain port, établit des connexions avec les clients et est capable de communiquer avec eux ou de les déconnecter. *

* Cette classe est thread-safe. * * @version 1.0 * @see Client * @see Connection */ public class Server implements Runnable { private ServerSocket server; liste privée Connexions; fil de discussion privé; private object final connectionsLock = new Object(); /** * Construit un {@code Server} qui interagit avec les clients sur le nom d'hôte et le port spécifiés avec la * longueur maximale demandée spécifiée d'une file d'attente de clients entrants. * * @param host Adresse de l'hôte à utiliser. * @param port Numéro de port à utiliser. * @param backlog Longueur maximale demandée de la file d'attente des clients entrants. * @throws NetworkException Si une erreur se produit lors du démarrage d'un serveur. */ public Server(String host, int port, int backlog) lève NetworkException { try { server = new ServerSocket(port, backlog, InetAddress.getByName(host)); } catch (UnknownHostException e) { throw new NetworkException("Le nom d'hôte n'a pas pu être résolu: " + host, e); } catch (IllegalArgumentException e) { throw new NetworkException("Le numéro de port doit être compris entre 0 et 65535 (inclus): " + port); } catch (IOException e) { throw new NetworkException("Le serveur n'a pas pu être démarré.", e); } connections = Collections.synchronizedList(new ArrayList()); thread = nouveau Thread (ceci); thread.start(); } /** * Construit un {@code Server} qui interagit avec les clients sur le nom d'hôte et le port spécifiés. * * @param host Adresse de l'hôte à lier. * @param port Numéro de port à lier. * @throws NetworkException Si des erreurs se produisent lors du démarrage d'un serveur. */ public Server(String host, int port) lève NetworkException { this(host, port, 50); } /** * Écoute, accepte et enregistre les connexions entrantes des clients. */ @Override public void run() { while (!server.isClosed()) { try { connections.add(new Connection(server.accept())); } catch (SocketException e) { if (!e.getMessage().equals("Socket fermé")) { e.printStackTrace(); } } catch (NetworkException | IOException e) { e.printStackTrace(); } } } /** * Envoie des données à tous les clients enregistrés. * * @param data Données à envoyer. * @throws IllegalStateException Si l'écriture de données est tentée lorsque le serveur est hors ligne. * @throws IllegalArgumentException Si les données à envoyer sont nulles. */ public void broadcast(Object data) { if (server.isClosed()) { throw new IllegalStateException("Données non envoyées, le serveur est hors ligne."); } if (data == null) { throw new IllegalArgumentException("null data"); } synchronisé (connectionsLock) { pour (Connection connection: connections) { try { connection.send(data); System.out.println("Données envoyées au client avec succès."); } catch (NetworkException e) { e.printStackTrace(); } } } } /** * Envoie un message de déconnexion et déconnecte le client spécifié. * * @param connection Client à déconnecter. * @throws NetworkException Si une erreur se produit lors de la fermeture de la connexion. */ public void disconnect(Connection connection) lève NetworkException { if (connections.remove(connection)) { connection.close(); } } /** * Envoie un message de déconnexion à tous les clients, les déconnecte et termine le serveur. */ public void close() lève NetworkException { synchronisé (connectionsLock) { for (Connection connection: connections) { try { connection.close(); } catch (NetworkException e) { e.printStackTrace(); } } } connections.clear(); essayez { server.close(); } catch (IOException e) { throw new NetworkException("Erreur lors de la fermeture du serveur."); } enfin { thread.interrupt(); } } /** * Renvoie si le serveur est en ligne ou non. * * @return True si le serveur est en ligne. Faux, sinon. */ public boolean isOnline() { return !server.isClosed(); } /** * Renvoie un tableau de clients enregistrés. */ public Connection getConnections() { synchronisé (connectionsLock) { return connections.toArray(new Connection[connections.size()]); } } }

Client.java

importer java.io. IOException; importer java.net. Socket; importer java.net. UnknownHostException; /** * La classe {@code Client} représente un point de terminaison client dans un réseau. {@code Client}, une fois connecté à un certain * serveur, est assuré de ne pouvoir communiquer qu'avec le serveur. Que d'autres clients reçoivent ou non les données * dépend de l'implémentation du serveur. *

* Cette classe est thread-safe. * * @version 1.0 * @see Server * @see Connection */ public class Client { private Connection connection; /** * Construit un {@code Client} connecté au serveur sur l'hôte et le port spécifiés. * * @param host Adresse de l'hôte à lier. * @param port Numéro de port à lier. * @throws NetworkException Si une erreur se produit lors du démarrage d'un serveur. */ public Client(String host, int port) lève NetworkException { try { connection = new Connection(new Socket(host, port)); } catch (UnknownHostException e) { throw new NetworkException("Le nom d'hôte n'a pas pu être résolu: " + host, e); } catch (IllegalArgumentException e) { throw new NetworkException("Le numéro de port doit être compris entre 0 et 65535 (inclus): " + port); } catch (IOException e) { throw new NetworkException("Le serveur n'a pas pu être démarré.", e); } } /** * Envoie des données à l'autre partie. * * @param data Données à envoyer. * @throws NetworkException Si l'écriture dans le flux de sortie échoue. * @throws IllegalStateException Si l'écriture de données est tentée lorsque la connexion est fermée. * @throws IllegalArgumentException Si les données à envoyer sont nulles. * @throws UnsupportedOperationException Si un type de données non pris en charge est tenté d'être envoyé. */ public void send(Object data) lève NetworkException { connection.send(data); } /** * Envoie un message de déconnexion et ferme la connexion avec le serveur. */ public void close() lève NetworkException { connection.close(); } /** * Renvoie si le client est connecté ou non au serveur. * * @return True si le client est connecté. Faux, sinon. */ public boolean isOnline() { return connection.isConnected(); } /** * Renvoie l'instance {@link Connection} du client. */ public Connection getConnection() { return connection; } }

Connexion.java

importer java.io. DataInputStream; importer java.io. DataOutputStream; importer java.io. IOException; importer java.net. Socket; importer java.net. SocketException; /** * La classe {@code Connection} représente soit une connexion du serveur au client, soit un point de terminaison client dans un réseau * {@code Connection}, une fois connecté, est capable d'échanger des données avec une ou plusieurs autres parties, selon sur une implémentation serveur *. *

* Cette classe est thread-safe. * * @version 1.0 * @see Server * @see Client */ public class Connection implements Runnable { private Socket socket; sortie DataOutputStream privée; DataInputStream privé dans; fil de discussion privé; Objet final privé writeLock = new Object(); objet final privé readLock = nouvel objet(); /** * Construit {@code Connection} en utilisant les flux d'un {@link Socket} spécifié. * * @param socket Socket pour récupérer les flux.*/ public Connection(Socket socket) throws NetworkException { if (socket == null) { throw new IllegalArgumentException("null socket"); } this.socket = socket; try { out = new DataOutputStream(socket.getOutputStream()); } catch (IOException e) { throw new NetworkException("Impossible d'accéder au flux de sortie.", e); } essayez { dans = new DataInputStream(socket.getInputStream()); } catch (IOException e) { throw new NetworkException("Impossible d'accéder au flux d'entrée.", e); } thread = nouveau Thread(ceci); thread.start(); } /** * Lit les messages pendant que la connexion avec l'autre partie est active. */ @Override public void run() { while (!socket.isClosed()) { try { int identifier; octet octets; synchronisé (readLock) { identifiant = in.readInt(); longueur int = in.readInt(); if (longueur > 0) { octets = nouvel octet[longueur]; in.readFully(octets, 0, octets.longueur); } else { continuer; } } switch (identifiant) { case Identifier. INTERNAL: String command = new String(bytes); if (commande.equals("déconnecter")) { if (!socket.isClosed()) { System.out.println("Paquet de déconnexion reçu."); essayez { fermer(); } catch (NetworkException e) { return; } } } Pause; case Identifier. TEXT: System.out.println("Message reçu: " + nouvelle chaîne (octets)); Pause; par défaut: System.out.println("Données non reconnues reçues."); } } catch (SocketException e) { if (!e.getMessage().equals("Socket fermé")) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } } } /** * Envoie des données à l'autre partie. * * @param data Données à envoyer. * @throws NetworkException Si l'écriture dans le flux de sortie échoue. * @throws IllegalStateException Si l'écriture de données est tentée lorsque la connexion est fermée. * @throws IllegalArgumentException Si les données à envoyer sont nulles. * @throws UnsupportedOperationException Si un type de données non pris en charge est tenté d'être envoyé. */ public void send(Object data) throws NetworkException { if (socket.isClosed()) { throw new IllegalStateException("Données non envoyées, la connexion est fermée."); } if (data == null) { throw new IllegalArgumentException("null data"); } int identifiant; octet octets; if (instance de données de String) { identifier = Identifier. TEXT; octets = ((chaîne) données).getBytes(); } else { throw new UnsupportedOperationException("Type de données non pris en charge: " + data.getClass()); } essayez { synchronisé (writeLock) { out.writeInt(identifier); out.writeInt(octets.longueur); out.write(octets); out.flush(); } } catch (IOException e) { throw new NetworkException("Les données n'ont pas pu être envoyées.", e); } } /** * Envoie un message de déconnexion et ferme la connexion avec l'autre partie. */ public void close() throws NetworkException { if (socket.isClosed()) { throw new IllegalStateException("La connexion est déjà fermée."); } essayez { byte message = "déconnecter".getBytes(); synchronisé (writeLock) { out.writeInt(Identifier. INTERNAL); out.writeInt(message.length); out.write(message); out.flush(); } } catch (IOException e) { System.out.println("Le message de déconnexion n'a pas pu être envoyé."); } essayez { synchronisé (writeLock) { out.close(); } } catch (IOException e) { throw new NetworkException("Erreur lors de la fermeture de la connexion.", e); } enfin { thread.interrupt(); } } /** * Renvoie si la connexion avec l'autre partie est active ou non. * * @return True si la connexion est active. Faux, sinon. */ public boolean isConnected() { return !socket.isClosed(); } }

Identifiant.java

/** * La classe {@code Identifier} contient des constantes utilisées par {@link Connection} pour sérialiser et désérialiser les données * envoyées sur le réseau. * * @version 1.0 * @see Connection */ public final class Identifier { /** * Identifiant pour les messages internes. */ public static final int INTERNAL = 1; /** * Identifiant pour les messages textuels. */ public static final int TEXT = 2; }

NetworkException.java

/** * La classe {@code NetworkException} indique une erreur liée au réseau. */ public class NetworkException extend Exception { /** * Construit une {@code NetworkException} avec {@code null} comme message. */ public NetworkException() { } /** * Construit une {@code NetworkException} avec le message spécifié. * * @param message Un message décrivant l'erreur. */ public NetworkException(String message) { super(message); } /** * Construit une {@code NetworkException} avec le message et la cause spécifiés. * * @param message Un message décrivant l'erreur. * @param cause Une cause d'erreur. */ public NetworkException(String message, Throwable cause) { super(message, cause); } /** * Construit une {@code NetworkException} avec la cause spécifiée. * * @param cause Une cause d'erreur. */ public NetworkException(Throwable cause) { super(cause); } }

Exemple d'utilisation.java

/** * La classe {@code UsageExample} montre l'utilisation de {@link Server} et {@link Client}. Cet exemple utilise * {@link Thread#sleep(long)} pour s'assurer que chaque segment est exécuté car un démarrage et une fermeture rapides empêchent certains * segments de s'exécuter. * * @version 1.0 * @see Server * @see Client */ public class UsageExample { public static void main(String args) throws Exception { String host = "localhost"; port int = 10430; Serveur serveur = nouveau serveur (hôte, port); Client client = nouveau Client (hôte, port); Thread.sleep (100L); client.send("Bonjour."); server.broadcast("Hé, mec!"); Thread.sommeil (100L); server.disconnect(server.getConnections()[0]); // ou client.close() pour se déconnecter du côté client server.close(); } }

Conseillé: