Programmation Avancée en C


socket_UDP_mcast_server.c

00001 #include <stdio.h> 
00002 #include <stdlib.h> 
00003 #include <unistd.h>
00004 #include <sys/socket.h>
00005 #include <netinet/in.h>
00006 #include <arpa/inet.h>
00007 #include <string.h>    
00008 
00009 #define MAX_SIZE 256
00010 #define GROUP   "239.15.10.06"  // Format: 239.jj.mm.yy  
00011 #define NUMPORT 6666
00012 
00013 void error(char * msg);
00014 int main() 
00015 {
00016     int sockfd = socket(PF_INET, SOCK_DGRAM, 0); // initialisation classique
00017     if (sockfd < 0) error("[socket]");
00018 
00019     struct sockaddr_in ip_mcast; // adresse de multicast du groupe (@IP+port)
00020     memset(&ip_mcast, 0, sizeof(ip_mcast));
00021     ip_mcast.sin_family      = AF_INET;
00022     if (inet_pton(AF_INET, GROUP, &(ip_mcast.sin_addr)) < 0) error("[inet_pton]");
00023     ip_mcast.sin_port        = htons(NUMPORT);    
00024  
00025     /* pour recevoir des données par multicast, il faut :
00026           1/ s'abonner au groupe
00027           2/ attacher la socket au port par bind */
00028     struct ip_mreq  gr_mcast;  
00029     gr_mcast.imr_multiaddr.s_addr = ip_mcast.sin_addr.s_addr;
00030     gr_mcast.imr_interface.s_addr = htons(INADDR_ANY);
00031     // abonnement de la socket au groupe multicast
00032     int rc = setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, 
00033                         &gr_mcast, sizeof(gr_mcast));
00034     if (rc < 0) error("setsockopt(IP_ADD_MEMBERSHIP)]");
00035     // Eventuellement, autorisé de lier plusieurs socket sur le port
00036     const int on = 1;
00037     rc = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
00038     if (rc < 0) error("[setsockopt(SO_REUSEADDR)]");
00039 
00040     // Attachement de la socket
00041     if (bind(sockfd, (struct sockaddr *) &ip_mcast, sizeof(ip_mcast)) < 0)
00042         error("[bind]");
00043     
00044     // On peut maintenant recevoir des données multicast
00045     char msg[MAX_SIZE];
00046     while (1) {
00047         ssize_t n = recvfrom(sockfd, msg, MAX_SIZE-1, 0, NULL, NULL);
00048         if (n < 0) error("[recvfrom]");
00049         msg[MAX_SIZE-1] = '\0';
00050         printf("Recv : %s\n",msg);
00051     }
00052     close(sockfd);
00053     return EXIT_SUCCESS;
00054 }
00055 
00056 void error(char * msg) {
00057     perror(msg);
00058     exit(EXIT_FAILURE);
00059 }