Con la trasmissione il client invia un messaggio a tutti gli utenti della rete e tutti i server rispondono. Con multicast si definisce un indirizzo di gruppo multicast e tutti i server si abbonano ad esso. Il client invia quindi un messaggio al gruppo, i server che hanno effettuato la sottoscrizione lo ricevono e rispondono.
Multicast è quando un mittente desidera inviare a un gruppo di destinatari, ad esempio quando un client di gioco desidera inviare a un (potenziale) gruppo di server. Gli indirizzi multicast sono indirizzi speciali in cui il sistema sa trattarli in modo diverso. Il destinatario comunica al sistema che desidera ricevere messaggi inviati a un determinato gruppo e il mittente invia un messaggio all'indirizzo del gruppo. Su una LAN funziona e basta. Attraverso le LAN è necessario il routing multicast che non è implementato sulla maggior parte delle reti. Ma la trasmissione non funzionerebbe su LAN.
L'uso di multicast garantisce che solo i sistemi della rete che si preoccupano di ricevere il messaggio lo riceveranno.
Il modo in cui lo implementate dipende dal linguaggio di programmazione ecc.
La struttura di un indirizzo multicast IPv6 è la seguente:
- Inizia sempre con i primi 8 bit dell'indirizzo impostati su 1, il che significa che saranno i primi due caratteri dell'indirizzo
ff
;
- Il 3o carattere (bit da 9 a 12) nell'indirizzo specifica i flag. Nel tuo caso probabilmente desideri un indirizzo multicast fisso per la tua applicazione. In tal caso il 3 ° carattere sarà un
0
che indica un indirizzo multicast assegnato in modo permanente;
- Il 4o carattere (bit da 13 a 16) determina l'ambito dell'indirizzo. Molto probabilmente userete il valore
2
per l'ambito link-local (LAN).
Insieme, questo significa che utilizzerai un indirizzo a partire da ff02:
.
Gli indirizzi multicast sono assegnati da IANA. RFC3307 definisce come farlo (il criterio è Expert Review, quindi non è necessario scrivere un RFC su ciò che stai facendo o qualcosa del genere). In questa risposta userò l'indirizzo multicast ff02::db8:aa:bb
, che è nel blocco riservato alla documentazione.
Non è necessario disporre dell'accesso root per utilizzare il multicast. I seguenti esempi di Python3.3 possono essere eseguiti con un normale account utente:
Il server (in ascolto sull'indirizzo 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)
E il client (inviando al gruppo multicast e ascoltando le risposte):
#!/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))
Ho usato Python 3.3 perché le versioni precedenti non hanno socket.if_nametoindex
, ma tutto il resto dovrebbe funzionare anche in Python 2.
PS: è una buona idea usare una libreria o un framework esistente per il rilevamento del servizio come suggerito in un'altra risposta. Utilizzerà il multicast sotto il cofano ma ti eviterà di dover progettare e implementare il tuo protocollo.