17 multicast示例

本文介绍组播通信的基本原理,包括组播IP地址范围与MAC地址格式,并通过具体代码示例展示了如何使用C语言实现服务器向组播组发送数据及客户端接收这些数据的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值