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);
相关推荐
('-')3 小时前
《从根上理解MySQL是怎样运行的》第十章学习笔记
笔记·学习·mysql
hd51cc3 小时前
MFC学习笔记 对话框
笔记·学习·mfc
誰能久伴不乏3 小时前
Linux文件套接字AF_UNIX
linux·服务器·c语言·c++·unix
Radan小哥3 小时前
Docker学习笔记—day0010
笔记·学习·docker
im_AMBER3 小时前
Canvas架构手记 05 鼠标事件监听 | 原生事件封装 | ctx 结构化对象
前端·笔记·学习·架构
JienDa3 小时前
JienDa聊PHP:电商实战中主流PHP框架的协同策略与架构优化
开发语言·架构·php
老神在在0013 小时前
Mybatis01
后端·学习·spring·java-ee·mybatis
JienDa3 小时前
JienDa聊PHP:起卦、卜卦平台实战中PHP框架的协同架构方略
开发语言·架构·php
Y***89083 小时前
Neo4j图数据库学习(二)——SpringBoot整合Neo4j
数据库·学习·neo4j