单播只能发送给一个接收方,但是当给多个接收者发送时,不仅仅耗费流量,而且耗费时间,总流量=每个接收者的流量*接受者。
广播方式是发送给所有的主机,广播的坏处是会造成信息污染,大量的信息会占用网络带宽。
多播(组播):只有加入某个多播组的主机才能接收到数据。多播既可以发给多个主机,又能避免像广播那样带来的过多的负荷。
组播的地址为D类地址:224.0.1.1-239.255.255.255
那么代码实现如下:
组播发送
#include <sys/socket.h> #include <sys/types.h> #include <arpa/inet.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <error.h> #include <string.h> #include <unistd.h> #include <time.h> #define MCAST_PORT 50001 #define MCAST_ADDR "239.0.0.1" #define error_exit(_errmsg_) error(EXIT_FAILURE, errno, _errmsg_) #define BUFF_SIZE 1024 int main() { int sockfd; struct sockaddr_in mcastaddr; char *buff = NULL; int nbytes; time_t time_sec; /**创建用户数据包套接字**/ == (sockfd = socket(AF_INET, SOCK_DGRAM, ))) error_exit("socket"); /**指定接收方地址为组播地址**/ mcastaddr.sin_family = AF_INET; mcastaddr.sin_port = htons(MCAST_PORT); mcastaddr.sin_addr.s_addr = inet_addr(MCAST_ADDR); /**连接到组播地址**/ == connect(sockfd, (struct sockaddr *)&mcastaddr, sizeof(mcastaddr))) error_exit("bind"); time(&time_sec); ) { sleep(); time_sec ++; buff = ctime(&time_sec); printf("%s", buff); /**数据发送**/ == send(sockfd, buff, strlen(buff), )) error_exit("send"); } close(sockfd); ; }
组播接收,有多个接收者
#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <strings.h> #define N 128 typedef struct sockaddr SA; int main(int argc, const char *argv[]) { int sockfd; /**创建用户数据包套接字**/ )) == -) { perror("socket"); exit(-); } struct sockaddr_in myaddr; myaddr.sin_family = AF_INET; myaddr.sin_addr.s_addr = inet_addr("239.0.0.1"); myaddr.sin_port = htons(); /**绑定多播IP**/ ) { perror("bind"); exit(-); } /* ** struct ip_mreq { ** struct in_addr imr_multiaddr; IP multicast address of group 设置多播组地址 ** struct in_addr imr_interface; local IP address of interface 本机IP ** }; */ /**加入多播组**/ struct ip_mreq mreq; bzero(&mreq, sizeof(mreq)); mreq.imr_multiaddr.s_addr = inet_addr("239.0.0.1"); mreq.imr_interface.s_addr = inet_addr(/*"0.0.0.0"*/"192.168.1.24"); ) { perror("setsockopt"); exit(-); } }; ) { /**等待接收数据**/ recvfrom(sockfd, buf, N, , NULL, NULL); printf("recv : %s\n", buf); } close(sockfd); ; }