Un guide d'UDP en Java

1. Vue d'ensemble

Dans cet article, nous explorerons la communication réseau avec Java, via le protocole UDP (User Datagram Protocol).

UDP est un protocole de communication qui transmet des paquets indépendants sur le réseau sans garantie d'arrivée et sans garantie de l'ordre de livraison .

La plupart des communications sur Internet ont lieu via le protocole TCP (Transmission Control Protocol), cependant, UDP a sa place que nous explorerons dans la section suivante.

2. Pourquoi utiliser UDP?

UDP est assez différent du TCP le plus courant. Mais avant de considérer les inconvénients d'UDP au niveau de la surface, il est important de comprendre que l'absence de surcharge peut le rendre beaucoup plus rapide que TCP.

Outre la vitesse, nous devons également nous rappeler que certains types de communication ne nécessitent pas la fiabilité de TCP mais privilégient plutôt une faible latence. La vidéo est un bon exemple d'application qui pourrait bénéficier de l'exécution sur UDP au lieu de TCP.

3. Création d'applications UDP

La construction d'applications UDP est très similaire à la construction d'un système TCP; la seule différence est que nous n'établissons pas de connexion point à point entre un client et un serveur.

La configuration est également très simple. Java est livré avec une prise en charge réseau intégrée pour UDP - qui fait partie du package java.net . Par conséquent , pour effectuer des opérations de mise en réseau sur UDP, nous ne devons importer les classes du java.net package: java.net.DatagramSocket et java.net.DatagramPacket .

Dans les sections suivantes, nous allons apprendre à concevoir des applications qui communiquent via UDP; nous utiliserons le protocole d'écho populaire pour cette application.

Tout d'abord, nous allons créer un serveur d'écho qui renvoie tout message qui lui est envoyé, puis un client d'écho qui envoie simplement n'importe quel message arbitraire au serveur et enfin, nous testerons l'application pour nous assurer que tout fonctionne correctement.

4. Le serveur

Dans la communication UDP, un seul message est encapsulé dans un DatagramPacket qui est envoyé via un DatagramSocket .

Commençons par configurer un serveur simple:

public class EchoServer extends Thread { private DatagramSocket socket; private boolean running; private byte[] buf = new byte[256]; public EchoServer() { socket = new DatagramSocket(4445); } public void run() { running = true; while (running) { DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet); InetAddress address = packet.getAddress(); int port = packet.getPort(); packet = new DatagramPacket(buf, buf.length, address, port); String received = new String(packet.getData(), 0, packet.getLength()); if (received.equals("end")) { running = false; continue; } socket.send(packet); } socket.close(); } }

Nous créons un DatagramSocket global que nous utiliserons tout au long pour envoyer des paquets, un tableau d'octets pour envelopper nos messages et une variable d'état appelée running .

Pour plus de simplicité, le serveur étend Thread , nous pouvons donc tout implémenter dans la méthode run .

À l'intérieur de run , nous créons une boucle while qui s'exécute juste jusqu'à ce que l' exécution soit modifiée en false par une erreur ou un message de fin du client.

En haut de la boucle, nous instancions un DatagramPacket pour recevoir les messages entrants.

Ensuite, nous appelons la méthode receive sur le socket. Cette méthode se bloque jusqu'à ce qu'un message arrive et stocke le message dans le tableau d'octets du DatagramPacket qui lui est passé.

Après avoir reçu le message, nous récupérons l'adresse et le port du client, puisque nous allons envoyer la réponse

retour.

Ensuite, nous créons un DatagramPacket pour envoyer un message au client. Notez la différence de signature avec le paquet de réception. Celui-ci nécessite également l'adresse et le port du client auquel nous envoyons le message.

5. Le client

Maintenant, déployons un client simple pour ce nouveau serveur:

public class EchoClient { private DatagramSocket socket; private InetAddress address; private byte[] buf; public EchoClient() { socket = new DatagramSocket(); address = InetAddress.getByName("localhost"); } public String sendEcho(String msg) { buf = msg.getBytes(); DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445); socket.send(packet); packet = new DatagramPacket(buf, buf.length); socket.receive(packet); String received = new String( packet.getData(), 0, packet.getLength()); return received; } public void close() { socket.close(); } }

Le code n'est pas si différent de celui du serveur. Nous avons notre DatagramSocket global et l'adresse du serveur. Nous les instancions à l'intérieur du constructeur.

Nous avons une méthode distincte qui envoie des messages au serveur et renvoie la réponse.

Nous convertissons d'abord le message de chaîne en un tableau d'octets, puis créons un DatagramPacket pour envoyer des messages.

Ensuite - nous envoyons le message. Nous convertissons immédiatement le DatagramPacket en un récepteur.

Lorsque l'écho arrive, nous convertissons les octets en une chaîne et renvoyons la chaîne.

6. Le test

Dans une classe UDPTest.java , nous créons simplement un test pour vérifier la capacité d'écho de nos deux applications:

public class UDPTest { EchoClient client; @Before public void setup(){ new EchoServer().start(); client = new EchoClient(); } @Test public void whenCanSendAndReceivePacket_thenCorrect() { String echo = client.sendEcho("hello server"); assertEquals("hello server", echo); echo = client.sendEcho("server is working"); assertFalse(echo.equals("hello server")); } @After public void tearDown() { client.sendEcho("end"); client.close(); } }

Dans la configuration , nous démarrons le serveur et créons également le client. Dans la méthode tearDown , nous envoyons un message de résiliation au serveur afin qu'il puisse fermer et en même temps nous fermons le client.

7. Conclusion

Dans cet article, nous avons découvert le protocole de datagramme utilisateur et créé avec succès nos propres applications client-serveur qui communiquent via UDP.

Pour obtenir le code source complet des exemples utilisés dans cet article, vous pouvez consulter le projet GitHub.