目录

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);
本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
viperrrrrrrrrr72 小时前
大数据学习(96)-Hive面试题
大数据·hive·学习
charlie1145141912 小时前
STM32F103C8T6单片机的起始点:使用GPIO输出点亮我们的第一个小灯(HAL库版本)
stm32·单片机·嵌入式硬件·学习·教程·hal库·gpio
暗碳3 小时前
vscode c语言环境配置
c语言·ide·vscode
郭涤生3 小时前
第三章:事务处理_《凤凰架构:构建可靠的大型分布式系统》
笔记·架构·系统架构
每次的天空3 小时前
Android学习总结之算法篇五(字符串)
android·学习·算法
奕天者4 小时前
C++学习笔记(三十三)——forward_list
c++·笔记·学习
郭涤生5 小时前
第七章:从类库到服务的分布式基石_《凤凰架构:构建可靠的大型分布式系统》
笔记·分布式·架构
武昌库里写JAVA5 小时前
Golang的消息中间件选型
java·开发语言·spring boot·学习·课程设计
breakloop6 小时前
量化交易从0到1(理论篇)
笔记·学习·量化交易
“逛丢一只鞋”6 小时前
从2G到5G:认证体系演进与网元架构变迁深度解析
5g·架构