Programmation Réseau
Multicast
Broadcast
[Link]@[Link]
!
UFR Informatique
!
2014
Multicast - Broadcast
La diffusion
• pour l’instant nous n’avons vu que de la
communication point à point
• mais il peut être utile ou nécessaire de
vouloir atteindre plusieurs destinataires
• C’est la diffusion
2
Multicast - Broadcast
La diffusion
• établir une connexion point à point fiable est
déjà relativement coûteux, alors une diffusion
fiable...
• C’est pourquoi n’est disponible que de la
diffusion non fiable
• on ne sait pas si même un destinataire a pu
lire le message…
3
Multicast - Broadcast
• la diffusion est disponible de deux façons
différentes :
• dans laquelle la diffusion s’effectue en
diffusion intégrale (broadcasting)
direction de toutes les machines d’un
réseau donné
• (multicasting) dans laquelle la diffusion
multidiffusion ou diffusion de groupe
s’effectue à destination d’applications
abonnées à un groupe
4
Multicast - Broadcast
• diffusion intégrale
• dans ce cas, la communication s’apparente à
celle de la diffusion d’un message à tout le
monde
• sirène incendie…
• multidiffusion
• dans ce cas, la communication s’apparente plutôt
à celle de la radiodiffusion ou de la télévision
• on s’abonne (en choisissant un canal)
5
Multicast - Broadcast
Les adresses et la diffusion
• Rappelons qu’il existe (en IPv4 et à l’origine) cinq classes
d’adresses :
• la classe A [Link] — [Link], soit 128
réseaux de 16M machines
• la classe B [Link] — [Link], soit 16k
réseaux de 64k machines
• la classe C [Link] — [Link], soit 2M
réseaux de 256 machines
• la classe D [Link] — [Link], réservée à la
multidiffusion
• la classe E [Link] — [Link]
6
Multicast - Broadcast
• la diffusion intégrale s’effectue en envoyant un
paquet à l’adresse de la « dernière » adresse
possible du réseau
• il existe un alias standard pour désigner l’adresse
de diffusion intégrale pour n’importe quel
réseau :
[Link]
• qui signifie donc (en théorie) « à toutes les
machines du réseau Internet »…
• est normalement limitée au réseau local (pas de
routage)
7
Multicast - Broadcast
• la multidiffusion s’effectue par utilisation d’un
groupe (identifié par une adresse de classe D)
• un groupe identifie un service de diffusion
• lorsqu’un message est émis à destination d’un
groupe, tous les membres peuvent recevoir un
exemplaire du message
• pour recevoir il faut être membre du groupe
• pour envoyer cela n’est pas nécessaire…
• est encore rarement (correctement) routée
8
Multicast - Broadcast
• pour l’envoi il est donc suffisant d’utiliser une
adresse de multidiffusion (classe D)
• en pratique on oubliera les adresses
224.x.x.x, 232.x.x.x, 233.x.x.x et
239.x.x.x (qui sont en partie réservées)
9
Broadcast
La diffusion intégrale aka broadcast
• le broadcast s’effectue normalement en
complémentant le masque de réseau puis en
l’additionnant à l’adresse du réseau
• ex : si je suis dans le réseau [Link]
que le masque de réseau est 0xFFFFFC00
alors l’adresse de diffusion est
[Link]
10
Broadcast - généralités
La diffusion intégrale aka broadcast
• la diffusion intégrale s’effectue en pratique
sur l’adresse [Link]
([Link])
• en fait un broadcast sur le réseau nul
[Link] qui correspond au réseau sur
lequel on est connecté (this du réseau)
• Tous les processus en écoute sur le port
concerné pourront recevoir le message
transmis
11
Broadcast - API Java
Réc
epte
import [Link].*; ur
!
public class Receiver {
public static void main(String args[]) {
try {
byte [] data = new byte[256];
DatagramSocket ds = new DatagramSocket(60123);
DatagramPacket dp =
new DatagramPacket(data,[Link]);
while (true) {
[Link](dp);
String s = new String([Link](),
0,[Link]());
[Link]("Received "+s);
}
} catch(Exception e) {
u l i er
[Link]();
ar ti c
}
de p
} R i e n
}
12
Broadcast - API Java
Envo
yeur
import [Link].*;
!
public class Sender {
public static void main(String args[]) {
try {
String s = "Ca va Paris ?";
DatagramSocket ds = new DatagramSocket();
DatagramPacket dp =
new DatagramPacket([Link](),
[Link]().length,
new InetSocketAddress("[Link]",60123));
[Link](dp);
} catch(Exception e) {
[Link](); u l i er
ar ti c
}
de p
} Ri e n
}
13
Broadcast - API C
API C
• en C il faut positionner la socket dans un
mode autorisant la diffusion intégrale à l’envoi
setsockopt()
• qui est une fonction permettant de modifier
les caractéristiques associées à une socket, et
ce à différentes niveaux de protocoles
• au moins au niveau socket SOL_SOCKET
• c’est assez similaire à fcntl() / ioctl()
14
Broadcast - API C
15
Broadcast - API C
• le niveau qui nous intéresse est SOL_SOCKET
• l’option d’activation du broadcast à l’envoi est
SO_BROADCAST
• Pour l’adresse d’envoi on peut utiliser le
symbole prédéfini INADDR_BROADCAST
16
Broadcast - API C
Envo
yeur
s = socket(AF_INET,SOCK_DGRAM,0);
bzero(&sin,sizeof(sin));
sin.sin_family = PF_INET;
sin.sin_port = htons(60123);
sin.sin_addr.s_addr =
htonl(INADDR_BROADCAST);
int e = 1;
r = setsockopt(s,SOL_SOCKET,
SO_BROADCAST,&e,sizeof(e));
r = sendto(s,msg,strlen(msg),0,
(struct sockaddr *)&sin,sizeof(sin));
peut être remplacé par
inet_addr("[Link]")
17
Broadcast - API C
Réc
epte
s = socket(AF_INET,SOCK_DGRAM,0); ur
bzero(&sin,sizeof(sin));
sin.sin_family = PF_INET;
sin.sin_port = htons(60123);
sin.sin_addr.s_addr = htonl(INADDR_ANY);
r = bind(s,(struct sockaddr *)&sin,sizeof(sin));
while (1) {
r = recv(s,msg,100,0);
if (r==-1) {
perror("recv");
close(s);
exit(EXIT_FAILURE);
}
msg[r] = '\0';
printf("Recu: %s\n",msg);
}
18
Multicast
La multidiffusion aka multicast
• le multicast s’effectue normalement en
choisissant une adresse de classe D :
• [Link] — [Link]
19
Mutilcast - API Java
• pour la réception il faut utiliser une
MulticastSocket
MulticastSocket(int port);
• et s’enregistrer comme membre d’un groupe
par appel à (par exemple)
void joinGroup(InetAddress groupe);
• la diffusion est limitée au TTL (Time To Live -
le nombre de routeurs à franchir)…
20
Multicast - API Java
• On peut sortir d’un groupe par appel à
void leaveGroupe(…);
• le reste de la communication est identique au
cas habituel
21
Multicast - API Java
try {
byte [] data = new byte[256];
InetAddress ia =
[Link]("[Link]");
MulticastSocket ms = new MulticastSocket(28888);
[Link](ia);
DatagramPacket dp =
new DatagramPacket(data,[Link]);
while (true) {
[Link](dp);
String s = new String([Link]()
0,[Link]());
[Link]("Received "+s);
}
} catch(Exception e) {
[Link]();
}
22
Multicast - API Java
try {
String s = "Bonjour la compagnie";
DatagramSocket ms =
new DatagramSocket();
InetAddress ia =
[Link]("[Link]");
DatagramPacket dp =
new DatagramPacket([Link](),
[Link]().length,ia,28888);
[Link](dp);
[Link]("Sent");
} catch(Exception e) {
[Link]();
}
23
Multicast - API C
• Attention selon les piles réseau, les appels peuvent être
légèrement différent, mais le principe est le même. Certains
noyaux Linux nécessitent l’activation du multicast. Consultez
la doc et le web.
• en C il est nécessaire de joindre le groupe avec un appel à :
setsockopt()
• qui est une fonction permettant de modifier les
caractéristiques associées à une socket, et ce à différentes
niveaux de protocoles
• au moins au niveau socket SOL_SOCKET
• c’est assez similaire à fcntl() / ioctl()
24
Multicast - API C
25
Multicast - API C
• le niveau qui nous intéresse est IPPROTO_IP
(documentée dans le manuel ip(4))
• la valeur est IP_ADD_MEMBERSHIP pour
rejoindre un groupe
• IP_DROP_MEMBERSHIP pour sortir du
groupe
• il existe d’autres valeurs
IP_MULTICAST_LOOP, IP_MULTICAST_IF,
IP_MULTICAST_TTL
26
Multicast - API C
• la valeur est exprimée à l’aide du type
struct ip_mreq {
/* multicast group to join */
struct in_addr imr_multiaddr;
/* interface to join on */
struct in_addr imr_interface;
};
27
Multicast - API C
• attention il peut être nécessaire (en général
ça l’est) d’autoriser plusieurs clients sur une
même machine à se joindre au groupe
• par conséquent il faut autoriser plusieurs
sockets à s’associer sur le port concerné…
• C’est encore un appel à setsockopt() qui le
permet au niveau socket (SOL_SOCKET)
• avec l’option SO_REUSEPORT
28
Multicast - API C Se
nd
int main(int argc, char *argv[]) { er
struct sockaddr_in addr;
int s; char *msg="Salut les gars!";
if ((s=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
perror("socket"); exit(EXIT_FAILURE);
}
bzero(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("[Link]");
addr.sin_port = htons(28888);
if (sendto(s,msg,strlen(msg),0,
(struct sockaddr *)&addr,sizeof(addr)) < 0) {
perror("sendto"); close(s); exit(EXIT_FAILURE);
}
close(s);
exit(EXIT_SUCCESS);
}
29
Multicast - API C Re
ce
iv
int main(int argc, char *argv[]) { er
struct sockaddr_in addr;
int s; struct ip_mreq mreq; char msg[256]; int ok=1;
if ((s=socket(AF_INET,SOCK_DGRAM,0)) < 0) {
perror("socket");
exit(EXIT_FAILURE);
}
if (setsockopt(s,SOL_SOCKET,SO_REUSEPORT,&ok,sizeof(ok)) < 0) {
perror("Reusing ADDR failed");
exit(EXIT_FAILURE);
}
bzero(&addr,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(28888);
if (bind(s,(struct sockaddr *)&addr,sizeof(addr)) < 0) {
perror("bind");
close(s);
exit(EXIT_FAILURE);
}
…
30
Multicast - API C Re
ce
iv
… er
mreq.imr_multiaddr.s_addr = inet_addr("[Link]");
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (setsockopt(s,IPPROTO_IP,IP_ADD_MEMBERSHIP,
&mreq,sizeof(mreq)) < 0) {
perror("Subscribing to group failed");
close(s); exit(EXIT_FAILURE);
}
while (1) {
bzero(msg,256);
if (recv(s,msg,256,0) < 0) {
perror("recv"); close(s); exit(EXIT_FAILURE);
}
printf("%s\n",msg);
}
return EXIT_SUCCESS;
}
31