Com a transmissão, o cliente envia uma mensagem para todos na rede e todos os servidores respondem. Com o multicast, você define um endereço de grupo multicast e todos os servidores o assinam. O cliente envia uma mensagem ao grupo, os servidores que se inscreveram a recebem e respondem.
O multicast é para quando um remetente deseja enviar para um grupo de receptores, como quando um cliente do jogo deseja enviar para um (potencial) grupo de servidores. Endereços multicast são endereços especiais em que o sistema sabe tratá-los de maneira diferente. O destinatário diz ao sistema que deseja receber as mensagens enviadas para um grupo específico e o remetente envia uma mensagem para o endereço do grupo. Em uma LAN, isso simplesmente funciona. Nas LANs, é necessário roteamento multicast que não é implementado na maioria das redes. Mas a transmissão também não funcionaria nas LANs.
O uso do multicast garante que apenas os sistemas da rede que se preocupam em receber a mensagem a recebam.
Como você implementa isso depende da linguagem de programação etc.
A estrutura de um endereço multicast IPv6 é a seguinte:
- Ele sempre começa com os primeiros 8 bits do endereço definido como 1, o que significa que os dois primeiros caracteres do endereço serão
ff
;
- O terceiro caractere (bits 9 a 12) no endereço especifica sinalizadores. No seu caso, você provavelmente deseja um endereço multicast fixo para o seu aplicativo. Nesse caso, o terceiro caractere será aquele
0
que indica um endereço multicast atribuído permanentemente;
- O quarto caractere (bits 13 a 16) determina o escopo do endereço. Você provavelmente usará o valor
2
para o escopo do link-local (LAN).
Juntos, isso significa que você usará um endereço começando com ff02:
.
Os endereços multicast são atribuídos pela IANA. O RFC3307 define como fazê-lo (o critério é Expert Review, portanto, não é necessário escrever um RFC sobre o que você está fazendo ou algo parecido). Nesta resposta, usarei o endereço multicast ff02::db8:aa:bb
, que está no bloco reservado para a documentação.
Você não precisa ter acesso root para usar o multicast. Os seguintes exemplos do Python3.3 podem ser executados com uma conta de usuário normal:
O servidor (escutando o endereço 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 o cliente (enviando para o grupo multicast e ouvindo as respostas):
#!/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))
Eu usei o Python 3.3 porque as versões mais antigas não têm socket.if_nametoindex
, mas todo o resto também deve funcionar no Python 2.
PS: usar uma biblioteca ou estrutura existente para descoberta de serviço, conforme sugerido em outra resposta, é uma boa idéia. Ele usará o multicast sob o capô, mas evitará que você precise projetar e implementar seu próprio protocolo.