1. 程式人生 > >一個多播例子的伺服器端與客戶端

一個多播例子的伺服器端與客戶端

下面是一個多播伺服器的例子。多播伺服器的程式設計很簡單,建立一個數據包套接字,選定多播的IP地址和埠,直接向此多播地址傳送資料就可以了。多播伺服器的程式設計,不需要伺服器加入多播組,可以直接向某個多播組傳送資料。


下面的例子持續向多播IP地址"224.0.0.88"的8888埠傳送資料"BROADCAST TEST DATA",每傳送一次間隔5s。

  1. /*  
  2. *broadcast_server.c - 多播服務程式  
  3. */  
  4. #define MCAST_PORT 8888;  
  5. #define MCAST_ADDR "224.0.0.88"//*一個區域性連線多播地址,路由器不進行轉發*/  
  6. #define MCAST_DATA "BROADCAST TEST DATA" /*多播發送的資料*  
  7. #define MCAST_INTERVAL 5                 /*傳送間隔時間*/  
  8. int main(int argc, char*argv)  
  9. {  
  10.     int s;  
  11.     struct sockaddr_in mcast_addr;        
  12. s = socket(AF_INET, SOCK_DGRAM, 0);  /*建立套接字*/  
  13.     if (s == -1)  
  14.     {  
  15.         perror("socket()");  
  16.         return -1;  
  17.     }  
  18.     memset(&mcast_addr, 0, sizeof(mcast_addr));/*初始化IP多播地址為0*/  
  19. mcast_addr.sin_family = AF_INET;        /*設定協議族類行為AF*/  
  20. mcast_addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);/*設定多播IP地址*/  
  21. mcast_addr.sin_port = htons(MCAST_PORT); /*設定多播埠*/  
  22.                                              /*向多播地址傳送資料*/  
  23.     while(1) {  
  24.         int n = sendto(s,                   /*套接字描述符*/  
  25.                             MCAST_DATA,     /*資料*/  
  26.                             sizeof(MCAST_DATA), /*長度*/  
  27.                             0,  
  28.                            (struct sockaddr*)&mcast_addr,   
  29.                            sizeof(mcast_addr)) ;  
  30.         if( n <0)  
  31.         {  
  32.             perror("sendto()");  
  33.             return -2;  
  34.         }         
  35.         sleep(MCAST_INTERVAL);            /*等待一段時間*/  
  36.     }  
  37.     return 0;  

11.3.6  一個多播例子的客戶端

多播組的IP地址為224.0.0.88,埠為8888,當客戶端接收到多播的資料後將打印出來。

客戶端只有在加入多播組後才能接受多播組的資料,因此多播客戶端在接收多播組的資料之前需要先加入多播組,當接收完畢後要退出多播組。

  1. /*  
  2. *broadcast_client.c - 多播的客戶端  
  3. */  
  4. #define MCAST_PORT 8888;  
  5. #define MCAST_ADDR "224.0.0.88"     /*一個區域性連線多播地址,路由器不進行轉發*/  
  6. #define MCAST_INTERVAL 5            /*傳送間隔時間*/  
  7. #define BUFF_SIZE 256              /*接收緩衝區大小*/  
  8. int main(int argc, char*argv[])  
  9. {     
  10.     int s;                          /*套接字檔案描述符*/  
  11.     struct sockaddr_in local_addr;  /*本地地址*/  
  12.     int err = -1;  
  13. s = socket(AF_INET, SOCK_DGRAM, 0);/*建立套接字*/  
  14.     if (s == -1)  
  15.     {  
  16.         perror("socket()");  
  17.         return -1;  
  18.     }     
  19.                                       /*初始化地址*/  
  20.     memset(&local_addr, 0, sizeof(local_addr));  
  21. local_addr.sin_family = AF_INET;  
  22. local_addr.sin_addr.s_addr = htonl(INADDR_ANY);  
  23. local_addr.sin_port = htons(MCAST_PORT);  
  24.                                        /*繫結socket*/  
  25. err = bind(s,(struct sockaddr*)&local_addr, sizeof(local_addr)) ;  
  26.     if(err <0)  
  27.     {  
  28.         perror("bind()");  
  29.         return -2;  
  30.     }  
  31.                                        /*設定迴環許可*/  
  32.     int loop = 1;  
  33. err = setsockopt(s,IPPROTO_IP, IP_MULTICAST_LOOP,&loop, sizeof(loop));  
  34.     if(err <0)  
  35.     {  
  36.         perror("setsockopt():IP_MULTICAST_LOOP");  
  37.         return -3;  
  38.     }  
  39.     struct ip_mreq mreq;                   /*加入廣播組*/  
  40. mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR); /*廣播地址*/  
  41. mreq.imr_interface.s_addr = htonl(INADDR_ANY);  /*網路介面為預設*/  
  42.                                                   /*將本機加入廣播組*/  
  43. err = setsockopt(s, IPPROTO_IP, IP_ADD_MEMBERSHIP,&mreq, sizeof   
  44.     (mreq));  
  45.     if (err <0)  
  46.     {  
  47.         perror("setsockopt():IP_ADD_MEMBERSHIP");  
  48.         return -4;  
  49.     }  
  50.     int times = 0;  
  51.     int addr_len = 0;  
  52.     char buff[BUFF_SIZE];  
  53.     int n = 0;  
  54.                            /*迴圈接收廣播組的訊息,5次後退出*/  
  55.     for(times = 0;times<5;times++)  
  56.     {  
  57. addr_len = sizeof(local_addr);  
  58.         memset(buff, 0, BUFF_SIZE);             /*清空接收緩衝區*/  
  59.                                                 /*接收資料*/  
  60. n = recvfrom(s, buff, BUFF_SIZE, 0,(struct sockaddr*)&local_addr,   
  61.         &addr_len);  
  62.         if( n== -1)   
  63.         {  
  64.             perror("recvfrom()");  
  65.         }  
  66.                                              /*列印資訊*/  
  67.         printf("Recv %dst message from server:%s\n", times, buff);  
  68.         sleep(MCAST_INTERVAL);   
  69.     }  
  70.                                             /*退出廣播組*/  
  71. err = setsockopt(s, IPPROTO_IP, IP_DROP_MEMBERSHIP,&mreq, sizeof   
  72.     (mreq));  
  73.     close(s);  
  74.     return 0;