【网络编程】组播的实现(C语言,linux,Ubuntu)

组播

1> 组播也是实现一对多的通信方式,对于广播而言,网络需要对每个消息进行复制转发,会占用大量的带宽,导致网络拥塞

2> 组播可以实现小范围的数据传播:将需要接收数据的接收端加入多播组,发送端向多播组中发送消息,每个组内成员都能接收到消息

3> 需要对接收端进行设置,将接收端加入多播组

1、需要使用setsockopt函数实现

2、需要对网络层设置:IPPROTO_IP

3、需要对加入多播组属性设置:IP_ADD_MEMBERSHIP

4、属性值的类型

struct ip_mreqn {

                struct in_addr imr_multiaddr; /* 组播地址:D类网络(224.0.0.0 --- 239.255.255.255) */ struct

                in_addr imr_address; /* 当前主机IP地址 */

                int imr_ifindex; /* 网卡编号: 通过指令 ip ad查看 */

                };

 

4> 组播也是使用UDP实现的,无论接收端是否愿意接收数据,发送端都可以正常向多播组中发送数据

5> 组播也分为发送端和接收端流程

组播发送端流程 -----> 类似于UDP的客户端流程

1、socket(); //创建用于通信的套接字文件描述符

2、bind(); //可选,可以绑定也可以不绑定

3、sendto(); //向多播组地址发送消息

4、close(); //关闭套接字

 

#include<myhead.h>
int main(int argc, const char *argv[])
{
	//创建socket
	int sfd = socket(AF_INET,SOCK_DGRAM,0);
	if(sfd ==-1)
	{
		perror("socket error");
		return -1;
	}
	//设置多播地址
	struct sockaddr_in min;
	min.sin_family = AF_INET;//通信🐟
	min.sin_port = htons(9999);//端口
	min.sin_addr.s_addr = inet_addr("224.6.6.6");//地址

	char wbuf[128] = "";
	while(1)
	{
		printf("请输入>>>>>");
		fgets(wbuf,sizeof(wbuf),stdin);
		wbuf[strlen(wbuf)-1]=0;
		sendto(sfd,wbuf,strlen(wbuf),0,(struct sockaddr*)&min,sizeof(min));
		printf("发送成功\n");
	}
	//关闭socket
	close(sfd);
	return 0;
}

组播的接收端流程 ------> 类似于UDP的服务器端流程

1、socket(); //创建用于通信的套接字文件描述符

2、bind(); //必须进行,但是,绑定的组播地址和端口号

3、setsockopt(); //加入多播组

4、sendto(); //向广播地址发送消息

5、close(); //关闭套接字

 

#include<myhead.h>

int main(int argc, const char *argv[])
{
    //1、socket();          //创建用于通信的套接字文件描述符
    int rfd = socket(AF_INET, SOCK_DGRAM, 0);
    if(rfd == -1)
    {
        perror("socket error");
        return -1;
    }

    //3、setsockopt();          //加入多播组
    //准备要设置的数据
    struct ip_mreqn imr;        
    imr.imr_multiaddr.s_addr = inet_addr("224.1.2.3");   //组播ip
    imr.imr_address.s_addr = inet_addr("192.168.0.143");   //主机ip
    imr.imr_ifindex = 2;                        //网卡编号
    if(setsockopt(rfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &imr, sizeof(imr)) == -1)
    {
        perror("setsockopt error");
        return -1;
    }
    printf("加入多播组成功\n");


    //2、bind();             //必须进行,但是,绑定的组播地址和端口号
    struct sockaddr_in rin;
    rin.sin_family = AF_INET;
    rin.sin_port = htons(9999);
    rin.sin_addr.s_addr = inet_addr("224.1.2.3");     //组播地址
    if(bind(rfd, (struct sockaddr*)&rin, sizeof(rin)) == -1)
    {
        perror("bind error");
        return -1;
    }
    printf("bind success\n");


    
    //4、recv();               //从组播地址中接受消息
    char rbuf[128] = "";
    while(1)
    {
        //清空容器
        bzero(rbuf, sizeof(rbuf));

        //接受广播消息
        recv(rfd, rbuf, sizeof(rbuf), 0);

        printf("收到组播消息为:%s\n", rbuf);
    }

    
    //5、close();                //关闭套接字
    close(rfd);

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值