Linux下实现多播(组播)

单播只能发送给一个接收方,但是当给多个接收者发送时,不仅仅耗费流量,而且耗费时间,总流量=每个接收者的流量*接受者。

广播方式是发送给所有的主机,广播的坏处是会造成信息污染,大量的信息会占用网络带宽。

多播(组播):只有加入某个多播组的主机才能接收到数据。多播既可以发给多个主机,又能避免像广播那样带来的过多的负荷。

组播的地址为D类地址:224.0.1.1-239.255.255.255

那么代码实现如下:

组播发送

 1 #include <sys/socket.h>
 2 #include <sys/types.h>
 3 #include <arpa/inet.h>
 4 #include <netinet/in.h>
 5 #include <stdio.h>
 6 #include <stdlib.h>
 7 #include <errno.h>
 8 #include <error.h>
 9 #include <string.h>
10 #include <unistd.h>
11 #include <time.h>
12 
13 #define MCAST_PORT    50001
14 #define MCAST_ADDR    "239.0.0.1"
15 
16 #define error_exit(_errmsg_)    error(EXIT_FAILURE, errno, _errmsg_)
17 
18 #define BUFF_SIZE    1024
19 
20 int main()
21 {
22     int sockfd;
23     struct sockaddr_in mcastaddr;
24     char *buff = NULL;
25     int nbytes;
26     time_t time_sec;
27     
28     /**创建用户数据包套接字**/
29     if (-1 == (sockfd = socket(AF_INET, SOCK_DGRAM, 0))) 
30         error_exit("socket");
31         
32     /**指定接收方地址为组播地址**/
33     mcastaddr.sin_family = AF_INET;
34     mcastaddr.sin_port = htons(MCAST_PORT);
35     mcastaddr.sin_addr.s_addr = inet_addr(MCAST_ADDR);
36     
37     /**连接到组播地址**/
38     if (-1 == connect(sockfd, (struct sockaddr *)&mcastaddr, sizeof(mcastaddr)))
39         error_exit("bind");
40 
41     time(&time_sec);
42     while (2)  {
43         sleep(1);
44         time_sec ++;
45         buff = ctime(&time_sec);
46         printf("%s", buff);
47         /**数据发送**/
48         if (-1 == send(sockfd, buff, strlen(buff), 0))
49             error_exit("send");
50     }
51     close(sockfd);
52 
53     return 0;
54 }

组播接收,有多个接收者

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <errno.h>
 4 #include <sys/types.h>
 5 #include <sys/socket.h>
 6 #include <netinet/in.h>
 7 #include <arpa/inet.h>
 8 #include <unistd.h>
 9 #include <string.h>
10 #include <strings.h>
11 
12 #define N 128
13 
14 typedef struct sockaddr SA;
15 
16 int main(int argc, const char *argv[])
17 {
18     int sockfd;
19     
20     /**创建用户数据包套接字**/
21     if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
22     {
23         perror("socket");
24         exit(-1);
25     }
26         
27     struct sockaddr_in myaddr;
28     myaddr.sin_family = AF_INET;
29     myaddr.sin_addr.s_addr = inet_addr("239.0.0.1");
30     myaddr.sin_port = htons(50001);
31     
32     /**绑定多播IP**/
33     if(bind(sockfd, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1)
34     {
35         perror("bind");
36         exit(-1);
37     }
38     
39     /*
40     ** struct ip_mreq  {
41     **     struct in_addr imr_multiaddr;   IP multicast address of group 设置多播组地址
42     **     struct in_addr imr_interface;   local IP address of interface  本机IP
43     ** };
44     */
45     /**加入多播组**/
46     struct ip_mreq mreq;
47     bzero(&mreq, sizeof(mreq));
48     mreq.imr_multiaddr.s_addr = inet_addr("239.0.0.1");
49     mreq.imr_interface.s_addr = inet_addr(/*"0.0.0.0"*/"192.168.1.24");
50         
51     if(setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0)
52     {
53         perror("setsockopt");
54         exit(-1);
55     }
56 
57     char buf[N] = {0};
58 
59     while(1)
60     {
61         /**等待接收数据**/
62         recvfrom(sockfd, buf, N, 0, NULL, NULL);
63         printf("recv : %s\n", buf);
64     }
65 
66     close(sockfd);
67     return 0;
68 }

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。