Diffusion et multidiffusion en Java

1. Introduction

Dans cet article, nous décrivons comment les communications un-à-tous (diffusion) et un-à-plusieurs (multidiffusion) peuvent être gérées en Java. Les concepts de diffusion et de multidiffusion décrits dans cet article sont basés sur le protocole UDP.

Nous commençons par un rapide récapitulatif des datagrammes et de la diffusion et de la manière dont ils sont implémentés en Java. Nous examinons également les inconvénients de la diffusion et proposons la multidiffusion comme alternative à la diffusion.

Enfin, nous concluons en discutant de la prise en charge de ces deux méthodes d'adressage en IPv4 et IPv6.

2. Récapitulatif du datagramme

Selon la définition officielle d'un datagramme, «un datagramme est un message indépendant et autonome envoyé sur le réseau dont l'arrivée, l'heure d'arrivée et le contenu ne sont pas garantis».

En Java, le package java.net expose les classes DatagramPacket et DatagramSocket qui peuvent être utilisées pour la communication via le protocole UDP. UDP est généralement utilisé dans les scénarios où une latence plus faible est plus importante que la livraison garantie, comme le streaming audio / vidéo, la découverte de réseau, etc.

Pour en savoir plus sur UDP et les datagrammes en Java, reportez-vous au guide UDP en Java.

3 . Diffusion

La diffusion est un type de communication un-à-tous, c'est-à-dire que l'intention est d'envoyer le datagramme à tous les nœuds du réseau. Contrairement au cas de la communication point à point, nous n'avons pas besoin de connaître l'adresse IP de l'hôte cible . Au lieu de cela, une adresse de diffusion est utilisée.

Conformément au protocole IPv4, une adresse de diffusion est une adresse logique sur laquelle les périphériques connectés au réseau sont autorisés à recevoir des paquets. Dans notre exemple, nous utilisons une adresse IP particulière, 255.255.255.255 , qui est l'adresse de diffusion du réseau local.

Par définition, les routeurs connectant un réseau local à d'autres réseaux ne transfèrent pas les paquets envoyés à cette adresse de diffusion par défaut. Plus tard, nous montrons également comment nous pouvons parcourir toutes les interfaces réseau et envoyer des paquets à leurs adresses de diffusion respectives.

Tout d'abord, nous montrons comment diffuser un message. Dans cette mesure, nous devons appeler la méthode setBroadcast () sur le socket pour lui faire savoir que le paquet doit être diffusé:

public class BroadcastingClient { private static DatagramSocket socket = null; public static void main((String[] args)) throws IOException { broadcast("Hello", InetAddress.getByName("255.255.255.255")); } public static void broadcast( String broadcastMessage, InetAddress address) throws IOException { socket = new DatagramSocket(); socket.setBroadcast(true); byte[] buffer = broadcastMessage.getBytes(); DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, 4445); socket.send(packet); socket.close(); } }

L'extrait suivant montre comment parcourir toutes les NetworkInterfaces pour trouver leur adresse de diffusion:

List listAllBroadcastAddresses() throws SocketException { List broadcastList = new ArrayList(); Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()) { NetworkInterface networkInterface = interfaces.nextElement(); if (networkInterface.isLoopback() || !networkInterface.isUp()) { continue; } networkInterface.getInterfaceAddresses().stream() .map(a -> a.getBroadcast()) .filter(Objects::nonNull) .forEach(broadcastList::add); } return broadcastList; }

Une fois que nous avons la liste des adresses de diffusion, nous pouvons exécuter le code dans la méthode broadcast () ci-dessus pour chacune de ces adresses.

Il n'y a pas de code spécial requis du côté récepteur pour recevoir un message diffusé. Nous pouvons réutiliser le même code qui reçoit un datagramme UDP normal. Un guide UDP en Java contient plus de détails sur ce sujet.

4. Multidiffusion

La diffusion est inefficace car les paquets sont envoyés à tous les nœuds du réseau, qu'ils soient intéressés ou non à recevoir la communication. Cela peut être un gaspillage de ressources.

La multidiffusion résout ce problème et envoie des paquets uniquement aux consommateurs intéressés. La multidiffusion est basée sur un concept d'appartenance à un groupe , où une adresse de multidiffusion représente chaque groupe.

Dans IPv4, toute adresse comprise entre 224.0.0.0 et 239.255.255.255 peut être utilisée comme adresse de multidiffusion. Seuls les nœuds qui s'abonnent à un groupe reçoivent des paquets communiqués au groupe.

En Java, MulticastSocket est utilisé pour recevoir des paquets envoyés à une adresse IP multicast. L'exemple suivant illustre l'utilisation de MulticastSocket :

public class MulticastReceiver extends Thread { protected MulticastSocket socket = null; protected byte[] buf = new byte[256]; public void run() { socket = new MulticastSocket(4446); InetAddress group = InetAddress.getByName("230.0.0.0"); socket.joinGroup(group); while (true) { DatagramPacket packet = new DatagramPacket(buf, buf.length); socket.receive(packet); String received = new String( packet.getData(), 0, packet.getLength()); if ("end".equals(received)) { break; } } socket.leaveGroup(group); socket.close(); } }

Après avoir lié le MulticastSocket à un port, nous appelons la méthode joinGroup () , avec l'adresse IP de multidiffusion comme argument. Ceci est nécessaire pour pouvoir recevoir les paquets publiés dans ce groupe. La méthode LeaveGroup () peut être utilisée pour quitter le groupe.

L'exemple suivant montre comment publier sur une adresse IP multicast:

public class MulticastPublisher { private DatagramSocket socket; private InetAddress group; private byte[] buf; public void multicast( String multicastMessage) throws IOException { socket = new DatagramSocket(); group = InetAddress.getByName("230.0.0.0"); buf = multicastMessage.getBytes(); DatagramPacket packet = new DatagramPacket(buf, buf.length, group, 4446); socket.send(packet); socket.close(); } }

5. Diffusion et IPv6

IPv4 prend en charge trois types d'adressage: monodiffusion, diffusion et multidiffusion. La diffusion, en théorie, est une communication un-à-tous, c'est-à-dire qu'un paquet envoyé depuis un appareil a le potentiel d'atteindre l'ensemble de l'Internet.

Comme cela n'est pas souhaité pour des raisons évidentes, la portée de la diffusion IPv4 a été considérablement réduite. La multidiffusion, qui constitue également une meilleure alternative à la diffusion, est arrivée beaucoup plus tard et a donc pris du retard dans son adoption.

Dans IPv6, la prise en charge de la multidiffusion est devenue obligatoire et il n'y a pas de concept explicite de diffusion. La multidiffusion a été étendue et améliorée afin que toutes les fonctionnalités de diffusion puissent désormais être implémentées avec une certaine forme de multidiffusion.

Dans IPv6, les bits les plus à gauche d'une adresse sont utilisés pour déterminer son type. Pour une adresse multicast, les 8 premiers bits sont tous des uns, c'est-à-dire FF00 :: / 8. En outre, les bits 113-116 représentent la portée de l'adresse, qui peut être l'une des 4 suivantes: Global, Site-local, Link-local, Node-local.

En plus de la monodiffusion et de la multidiffusion, IPv6 prend également en charge toute diffusion, dans laquelle un paquet peut être envoyé à n'importe quel membre du groupe, mais n'a pas besoin d'être envoyé à tous les membres.

6. Résumé

Dans cet article, nous avons exploré les concepts de type de communication un-à-tous et un-à-plusieurs à l'aide du protocole UDP. Nous avons vu des exemples de mise en œuvre de ces concepts en Java.

Enfin, nous avons également exploré le support IPv4 et IPv6.

Un exemple de code complet est disponible sur Github.