【Linux网络编程(四)】多播编程流程

多播

数据的收发仅仅在同一分组中进行

1 多播的特点:

1、多播地址标示一组接口
2、多播可以用于广域网使用
3、在IPv4中,多播是可选的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n03KXQtk-1662294908423)(1、客户端的流程:下载文件.assets/image-20220831231402022.png)]




2 多播地址

IPv4的D类IP地址是多播地址
  十进制:224.0.0.1 ~ 239.255.255.254(里面任意一个都是多播地址)
    十六进制:E0.00.00.01 ~ EF.FF.FF.FE

多播地址向以太网MAC地址的映射(MAC地址不能直接全部设为FF,需要进行过滤)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0hQCRtpE-1662294908424)(1、客户端的流程:下载文件.assets/image-20220831231929903.png)]




3 多播的工作流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r2pUaOTg-1662294908426)(1、客户端的流程:下载文件.assets/image-20220831232429546.png)]

只能将自己主机的IP加入多播组

基于mac地址不完备硬件过滤

基于IP地址的完备软件过滤




4 加入或退出多播组

多播套接口选项

int setsockopt(int sockfd, int level,int optname,   
                const void *optval, socklen_t optlen);
/*
​	sockfd:加入或退出的套接字

​	level: SOL_SOCKET:广播属性
            IPPROTO_IP:组播属性

​	optname:IP_ADD_MEMBERSHIP: 加入组播
			 IP_DROP_MEMBERSHIP:退出组播 

​	optval:ip_mreq结构体

​	optlen:ip_mreq结构体长度-

	成功返回0,否则返回-1
*/                

在这里插入图片描述

ip_mreq{} 多播地址结构体

在IPv4因特网域(AF_INET)中,多播地址结构体用如下结构体ip_mreq表示:

struct in_addr
{
	in_addr_t s_addr;
}

struct ip_mreq
{
	struct in_addr imr_multiaddr; //多播组IP
	struct in_addr imr_interface; //将要添加到多播组的IP
	
	/*将imr_interface添加到imr_multiaddr中*/
};



5 多播流程代码

5.1 多播发送端

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>

int main(int argc, char const *argv[])
{
	int sockfd = socket(AF_INET,SOCK_DGRAM,0);//创建套接字
    if(sockfd<0)
    {
        perror("sockfd");
        return -1;
    }
 
    struct sockaddr_in server,client;	//创建结构体存储发送端,接收端的信息
    server.sin_family=AF_INET;
    server.sin_port=htons(8000);
    server.sin_addr.s_addr=inet_addr(224.0.0.1);
    int n=sizeof(server);

	char buf[64]={0};	//缓冲区
    int m=sizeof(client);
    while(1)
    {
    	
    	fgets(buf,sizeof(buf),stdin);	//从终端输入
    	buf[strlen(buf)-1]='\0';	//处理输入的回车
    	
        sendto(sockfd,buf,strlen(buf),0,(struct sockaddr*)&server,m);//发送数据
        
        memset(buf,0,sizeof(buf));//清空缓冲区
    }
    close(sockfd);
 
    return 0;

5.2 多播接收端

#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <arpa/inet.h>

int main(int argc, char const *argv[])
{
    //创建一个udp套接字
    int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
     if(sockfd<0)
    {
        perror("sockfd");
        return -1;
    }

    //bind绑定固定的IP端口
    struct sockaddr_in my_addr;
    bzero(&my_addr, sizeof(my_addr));
    my_addr.sin_family = AF_INET;
    my_addr.sin_port = htons(8000);
    my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    bind(sockfd, (struct sockaddr *)&my_addr, sizeof(my_addr));
	
	//将sockfd加入多播组224.0.0.1
	struct ip_mreq mreq;
	mreq.imr_multiaddr.s_addr = inet_addr("224.0.0.1"); //多播组IP
	mreq.imr_interface.s_addr = hton1(INADDR_ANY);		//主机所有IP
	setsockopt(sockfd, IPPORT_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));

	//测试接收多播组的消息
	while(1)
	{
		unsigned char buf[1500] = "";
		recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL);
		printf("buf = %s \n",buf);
	}

    close(sockfd);
    return 0;
}

客服端

千峰物联网___网络编程___广播

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eiker_3169

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值