Avec la diffusion, le client envoie un message à tout le monde sur le réseau et tous les serveurs répondent. Avec la multidiffusion, vous définissez une adresse de groupe de multidiffusion et tous les serveurs y souscrivent. Le client envoie alors un message au groupe, les serveurs abonnés le reçoivent et répondent.
La multidiffusion est destinée à lorsqu'un expéditeur souhaite envoyer à un groupe de récepteurs, comme lorsqu'un client de jeu souhaite envoyer à un groupe (potentiel) de serveurs. Les adresses de multidiffusion sont des adresses spéciales où le système sait les traiter différemment. Le récepteur indique au système qu'il souhaite recevoir les messages envoyés à un groupe particulier, et l'expéditeur envoie un message à l'adresse du groupe. Sur un LAN, cela fonctionne. Sur les réseaux locaux, vous avez besoin d'un routage multidiffusion qui n'est pas implémenté sur la plupart des réseaux. Mais la diffusion ne fonctionnerait pas non plus sur les réseaux locaux.
L'utilisation de la multidiffusion garantit que seuls les systèmes du réseau soucieux de recevoir le message le recevront.
La façon dont vous implémentez cela dépend du langage de programmation, etc.
La structure d'une adresse de multidiffusion IPv6 est la suivante:
- Il commence toujours par les 8 premiers bits de l'adresse mis à 1, ce qui signifie que les deux premiers caractères de l'adresse seront
ff
;
- Le 3ème caractère (bits 9 à 12) dans l'adresse spécifie les drapeaux. Dans votre cas, vous souhaitez probablement une adresse de multidiffusion fixe pour votre application. Dans ce cas, le 3ème caractère sera un
0
qui indique une adresse de multidiffusion attribuée en permanence;
- Le 4ème caractère (bits 13 à 16) détermine la portée de l'adresse. Vous utiliserez très probablement la valeur
2
de la portée de liaison locale (LAN).
Ensemble, cela signifie que vous utiliserez une adresse commençant par ff02:
.
Les adresses de multidiffusion sont attribuées par l'IANA. Le RFC3307 définit comment le faire (le critère est Expert Review, il n'est donc pas nécessaire d'écrire un RFC sur ce que vous faites ou quelque chose comme ça). Dans cette réponse, j'utiliserai l'adresse de multidiffusion ff02::db8:aa:bb
, qui se trouve dans le bloc réservé à la documentation.
Vous n'avez pas besoin d'avoir un accès root pour utiliser la multidiffusion. Les exemples Python3.3 suivants peuvent être exécutés avec un compte d'utilisateur normal:
Le serveur (écoute sur l'adresse multicast):
#!/usr/bin/env python3.3
import socket
import struct
if_idx = socket.if_nametoindex('en0')
addr = 'ff02::db8:aa:bb'
port = 42424
group = socket.inet_pton(socket.AF_INET6, addr) + struct.pack("I", if_idx)
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_JOIN_GROUP, group)
sock.bind(('::', port))
while True:
msg, sender = sock.recvfrom(1024)
print('Received "%s" from "%s"' % (str(msg, 'UTF-8'), sender))
sock.sendto(bytes('Received %d bytes from you' % len(msg), 'UTF-8'), sender)
Et le client (envoi au groupe de multidiffusion et écoute les réponses):
#!/usr/bin/env python3.3
import socket
if_idx = socket.if_nametoindex('en0')
addr = 'ff02::db8:aa:bb'
port = 42424
sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_MULTICAST_IF, if_idx)
sock.sendto(bytes('Hello there!', 'UTF-8'), (addr, port))
while True:
# You probably wait a certain time for replies, not indefinitely like this example
msg, sender = sock.recvfrom(1024)
print('Received "%s" from "%s"' % (str(msg, 'UTF-8'), sender))
J'ai utilisé Python 3.3 parce que les anciennes versions n'en ont pas socket.if_nametoindex
, mais tout le reste devrait également fonctionner en Python 2.
PS: utiliser une bibliothèque ou un framework existant pour la découverte de services comme suggéré dans une autre réponse est une bonne idée. Il utilisera la multidiffusion sous le capot, mais vous évitera d'avoir à concevoir et à mettre en œuvre votre propre protocole.