Un guide pour UDP en Java

Un guide pour UDP en Java

1. Vue d'ensemble

Dans cet article, nous explorerons la communication réseau avec Java, via le protocole de datagramme utilisateur (UDP).

UDP est un protocole de communication quitransmits independent packets over the network with no guarantee of arrival and no guarantee of the order of delivery.

La plupart des communications sur Internet se font 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 plus commun. Mais avant de considérer les inconvénients de l'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é du protocole TCP, mais valorisent 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 très simple aussi. Java est livré avec une prise en charge réseau intégrée pour UDP - qui fait partie du packagejava.net. Par conséquent, pour effectuer des opérations de mise en réseau via UDP, il suffit d'importer les classes du packagejava.net:java.net.DatagramSocket etjava.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 tout 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 unDatagramPacket qui est envoyé via unDatagramSocket.

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 unDatagramSocket global que nous utiliserons partout pour envoyer des paquets, un tableau d'octets pour envelopper nos messages et une variable d'état appeléerunning.

Pour plus de simplicité, le serveur étendThread, nous pouvons donc tout implémenter dans la méthoderun.

À l'intérieur derun, nous créons une boucle while qui s'exécute juste jusqu'à ce querunning soit changé en faux par une erreur ou un message de fin du client.

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

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

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

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

5. Le client

Lançons maintenant 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 nosDatagramSocketglobaux et l'adresse du serveur. Nous les instancions dans le 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 unDatagramPacket pour l'envoi de messages.

Ensuite, nous envoyons le message. Nous convertissons immédiatement lesDatagramPacket en un récepteur.

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

6. Le test

Dans une classeUDPTest.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();
    }
}

Danssetup, nous démarrons le serveur et créons également le client. Dans la méthodetearDown, nous envoyons un message de terminaison 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 construit 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 lesGitHub project.