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