C/S架构学习之组播

  • 组播:
  • 过多的广播会占用网络带宽,产生广播风暴的现象,从而影响正常的通信活动;
  • 组播(或者多播)是局域网内部的通信,只有加入到某个多播组的主机才能收到数据;
  • 组播的方式既可以发给多个主机,又能避免广播带来过多的网络负载;
  • 组播地址 :D类地址:"224.0.0.1~239.255.255.254";
  • 设置组播的流程:
  • 发送方(UDP的客户端):
  • 一、创建用户数据报套接字(socket函数):
c 复制代码
	int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(-1 == sockfd)
    {
        perror("socket error");
        exit(-1);

    }
  • 二、填充组播信息结构体( struct sockaddr_in):
c 复制代码
	struct sockaddr_in serveraddr;
    socklen_t serveraddr_len = sizeof(serveraddr);
    memset(&serveraddr,0,serveraddr_len);
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(M_IP);
    serveraddr.sin_port = htons(PORT);
  • 三、发送组播信息(sendto函数):
c 复制代码
	char buf[128] = {0};
    while(true)
    {
        memset(buf,0,sizeof(buf));
        fgets(buf,128,stdin);
        buf[strlen(buf)-1] = '\0';
        if(!strncmp(buf,"quit",4))
        {

            break;

        }

        //给服务器发送数据
        if(-1 == (sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr*)&serveraddr,serveraddr_len)))
        {
            perror("sendto error");
            exit(-1);

        }
    }
  • 四、关闭用户数据报套接字(close函数):
c 复制代码
 	close(sockfd);
  • 接收方(UDP的服务器):
  • 一、创建用户数据报套接字(socket函数):
c 复制代码
	int sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(-1 == sockfd)
    {
        perror("socket error");
        exit(-1);

    }
  • 二、填充组播信息结构体(struct sockaddr_in):
c 复制代码
	struct sockaddr_in serveraddr,clientaddr;
    socklen_t serveraddr_len = sizeof(serveraddr);
    socklen_t clientaddr_len = sizeof(clientaddr);
    memset(&serveraddr,0,serveraddr_len);
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_addr.s_addr = inet_addr(M_IP);
    serveraddr.sin_port = htons(PORT);
  • 三、用户数据报套接字和广播信息结构体绑定(bind函数):
c 复制代码
	if(-1 == (bind(sockfd,(struct sockaddr *)&serveraddr,serveraddr_len)))
    {
        perror("bind error");
        exit(-1);
    }
  • 四、设置加入多播组(setsockopt函数):
c 复制代码
	struct ip_mreqn {

        struct in_addr imr_multiaddr; 
        struct in_addr imr_address;   
        int            imr_ifindex;   

    };
    struct ip_mreqn multi_group;
    multi_group.imr_address.s_addr = INADDR_ANY;
    multi_group.imr_multiaddr.s_addr = inet_addr(M_IP);
    multi_group.imr_ifindex = 0;

    if(-1 == (setsockopt(sockfd,IPPROTO_IP,IP_ADD_MEMBERSHIP,&multi_group,sizeof(multi_group))))
    {

        perror("setsockopt error");
        exit(-1);

    }
  • 五、接收组播信息(recvfrom函数):
c 复制代码
	char buf[128] = {0};
    while(true)
    {
        memset(buf,0,sizeof(buf));
        if(-1 == recvfrom(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&clientaddr,&clientaddr_len))
        {
            perror("recvfrom error");
            exit(-1);
        }
        printf("客户端[%s:%d]发来数据[%s]\n",inet_ntoa(clientaddr.sin_addr),ntohs(clientaddr.sin_port),buf);
    }
  • 六、关闭用户数据报套接字(close函数):
c 复制代码
 	close(sockfd);
相关推荐
liliangcsdn7 分钟前
Leiden社区发现算法的学习和示例
学习·数据分析·知识图谱
房开民1 小时前
使用海康机器人相机SDK实现基本参数配置(C语言示例)
c语言·数码相机·机器人
南山二毛1 小时前
机器人控制器开发(导航算法——导航栈关联坐标系)
人工智能·架构·机器人
DKPT1 小时前
JVM中如何调优新生代和老生代?
java·jvm·笔记·学习·spring
phltxy1 小时前
JVM——Java虚拟机学习
java·jvm·学习
只因在人海中多看了你一眼2 小时前
B.50.10.10-微服务与电商应用
微服务·云原生·架构
Tina表姐2 小时前
(C题|NIPT 的时点选择与胎儿的异常判定)2025年高教杯全国大学生数学建模国赛解题思路|完整代码论文集合
c语言·开发语言·数学建模
喂完待续3 小时前
【序列晋升】29 Spring Cloud Task 微服务架构下的轻量级任务调度框架
java·spring·spring cloud·云原生·架构·big data·序列晋升
高山有多高4 小时前
详解文件操作
c语言·开发语言·数据库·c++·算法
m0_571372824 小时前
嵌入式学习——ARM 体系架构1
arm开发·学习