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);
相关推荐
稻草人222216 小时前
java Excel 导出 ,如何实现八倍效率优化,以及代码分层,方法封装
后端·架构
数据智能老司机17 小时前
精通 Python 设计模式——创建型设计模式
python·设计模式·架构
数据智能老司机18 小时前
精通 Python 设计模式——SOLID 原则
python·设计模式·架构
bobz9651 天前
k8s svc 实现的技术演化:iptables --> ipvs --> cilium
架构
云舟吖1 天前
基于 electron-vite 实现一个 RPA 网页自动化工具
前端·架构
brzhang1 天前
当AI接管80%的执行,你“不可替代”的价值,藏在这20%里
前端·后端·架构
Lei活在当下1 天前
【业务场景架构实战】4. 支付状态分层流转的设计和实现
架构·android jetpack·响应式设计
架构师沉默2 天前
设计多租户 SaaS 系统,如何做到数据隔离 & 资源配额?
java·后端·架构
kfyty7252 天前
不依赖第三方,不销毁重建,loveqq 框架如何原生实现动态线程池?
java·架构
刘立军2 天前
本地大模型编程实战(33)用SSE实现大模型的流式输出
架构·langchain·全栈