1、組播IP地址
224.0.0.0 ~ 239.255.255.255
組播以太網地址(MAC地址)
開頭高三個字節總是 01:00:5e
2、組播分爲兩部分:
a、組播數據流 ,目的MAC地址爲01:00:5e:xx:xx:xx
224.25.25.25 的mac地址爲01:00:5e:19:19:19
b、組播控制流(IGMP v1,v2,v3)
分三種報文:report(join),leave,query
3. server往組發送信息
#include "socket_includes.h"
#include <errno.h>
int main(int argc, char*argv)
{
int sockfd;
struct sockaddr_in mcast_addr;
char buf[100] = MCAST_DATA;
int on = 1;
int ret;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{
perror("socket()");
return -1;
}
if((ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) < 0){
perror("Error, set socket reuse addr failed");
return -1;
}
memset(&mcast_addr, 0, sizeof(mcast_addr));
mcast_addr.sin_family = AF_INET;
mcast_addr.sin_addr.s_addr = inet_addr(MCAST_ADDR);
mcast_addr.sin_port = htons(MCAST_PORT);
while(1) {
int n = sendto(sockfd, buf, strlen(buf), 0,
(struct sockaddr*)&mcast_addr,sizeof(mcast_addr));
if( n < 0){
perror("sendto:");
return -1;
}
sleep(MCAST_INTERVAL);
}
return 0;
}
4. client接收信息
#include "socket_includes.h"
int main(int argc, char*argv[])
{
int sockfd;
struct sockaddr_in local_addr;
int err = -1;
int ret;
int on = 1;
int times = 0;
int addr_len = 0;
char buff[BUFF_SIZE];
int n = 0;
int loop = 1;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1)
{
perror("socket()");
return -1;
}
if((ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) < 0){
perror("Error, set socket reuse addr failed");
return -1;
}
memset(&local_addr, 0, sizeof(local_addr));
local_addr.sin_family = AF_INET;
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
local_addr.sin_port = htons(MCAST_PORT);
err = bind(sockfd,(struct sockaddr*)&local_addr, sizeof(local_addr)) ;
if(err < 0)
{
perror("bind()");
return -1;
}
err = setsockopt(sockfd,IPPROTO_IP, IP_MULTICAST_LOOP, &loop, sizeof(loop));
if(err < 0){
perror("setsockopt():IP_MULTICAST_LOOP");
return -1;
}
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = inet_addr(MCAST_ADDR);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
err = setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
if (err < 0){
perror("setsockopt():IP_ADD_MEMBERSHIP");
return -1;
}
for(times = 0;times<5;times++){
addr_len = sizeof(local_addr);
memset(buff, 0, BUFF_SIZE);
n = recvfrom(sockfd, buff, BUFF_SIZE, 0,(struct sockaddr*)&local_addr,&addr_len);
if(n == -1){
perror("recvfrom()");
break;
}
printf("Recv %dst message from server:%s\n", times, buff);
sleep(MCAST_INTERVAL);
}
err = setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP,&mreq, sizeof(mreq));
close(sockfd);
return 0;
}