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);
相关推荐
嵌入式科普12 分钟前
十一、从0开始卷出一个新项目之瑞萨RA6M5串口DTC接收不定长
c语言·stm32·cubeide·e2studio·ra6m5·dma接收不定长
A懿轩A15 分钟前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
居居飒24 分钟前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
思忖小下25 分钟前
梳理你的思路(从OOP到架构设计)_简介设计模式
设计模式·架构·eit
kkflash31 小时前
提升专业素养的实用指南
学习·职场和发展
1 9 J1 小时前
数据结构 C/C++(实验五:图)
c语言·数据结构·c++·学习·算法
仍然探索未知中3 小时前
C语言经典100例
c语言
6.943 小时前
Scala——身份证号码查询籍贯
学习·scala
爱吃西瓜的小菜鸡3 小时前
【C语言】矩阵乘法
c语言·学习·算法
初学者7.4 小时前
Webpack学习笔记(2)
笔记·学习·webpack