当前位置: 首页 > article >正文

Linux网络编程之---组播和广播

一.组播

1.概述

单播地址标识单个IP 接口,广播地址标识某个子网的所有IP 接口,
多播地址标识一组IP 接口。单播和广播是寻址方案的两个极端(要么单个要么全部),
多播则意在两者之间提供一种折中方案。多播数据报只应该由对它感兴趣的接口接收,
也就是说由运行相应多播会话应用系统的主机上的接口接收。
另外,广播一般局限于局域网内使用,而多播则既可以用于局域网,也可以跨广域网使用。

a.组播既可以用于局域网,也可以用于广域网
b.客户端需要加入多播组,才能接收到多的数据

2.api介绍

int setsockopt(int sockfd, int level, int opetname, const void *optval, socklen_t optlen)
    服务器设置多播的信息,外出接口
    -level : IPPROTO_IP
    - optname : IP_MULTICAS_IF
    - optval : struct in_addr

    客户端加入到多播组
    -level : IPPROTO_IP
    -optname : IP_ADD_MEMBERSHIP
    -optval : struct mreqn

3.服务端和客户端代码实现

3.1.serer

#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>


int main()
{
    int udp_sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(udp_sockfd == -1)
    {
        perror("socket");
        exit(-1);
    }


    //设置多播的属性,设置外出接口
    struct in_addr imr_multiaddr;
    inet_pton(AF_INET,"239.0.0.10",&imr_multiaddr.s_addr);
    setsockopt(udp_sockfd,IPPROTO_IP,IP_MULTICAST_IF,&imr_multiaddr,sizeof(imr_multiaddr));

    //创建客户端的地址信息
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr("239.0.0.10"); //广播地址
    server.sin_port = htons(8000);

    
    int num = 0;
    while(1)
    {
        char sendBuf[128];
        sprintf(sendBuf,"hello,client-----%d\n",num++);
        //发送数据
        sendto(udp_sockfd,sendBuf,strlen(sendBuf)+1,0,
                (const struct sockaddr*)&server,sizeof(server));
        printf("组播数据:%s\n",sendBuf);
        sleep(1);
    }
    close(udp_sockfd);
    return 0;
}

3.2.client

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>

int main() {

    // 1.创建一个通信的socket
    int fd = socket(PF_INET, SOCK_DGRAM, 0);
    if(fd == -1) {
        perror("socket");
        exit(-1);
    }   

    struct in_addr in;
    // 2.客户端绑定本地的IP和端口
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(9999);
    addr.sin_addr.s_addr = INADDR_ANY;

    int ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
    if(ret == -1) {
        perror("bind");
        exit(-1);
    }

    struct ip_mreq op;
    inet_pton(AF_INET, "239.0.0.10", &op.imr_multiaddr.s_addr);
    op.imr_interface.s_addr = INADDR_ANY;

    // 加入到多播组
    setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, &op, sizeof(op));

    // 3.通信
    while(1) {
        
        char buf[128];
        // 接收数据
        int num = recvfrom(fd, buf, sizeof(buf), 0, NULL, NULL);
        printf("server say : %s\n", buf);

    }

    close(fd);
    return 0;
}

二.广播

1.概述

向子网中多台计算机发送消息,并且子网中所有的计算机都可以接收到发送方发送的消息,
每个广播消息都包含一个特殊的IP地址,这个P中子网内主机标志部分的二进制全部为1。

a.只能在局域网中使用
b.客户端需要绑定服务器广播使用的端口,才可以接收到广播消息

 2.api介绍

//设置广播属性的函数
int setsockopt(int sockfd, int level, int opetname, const void *optval, socklen_t optlen)

    -sockfd : 文件描述符
    -level : SOL_SOCKET
    -optname : SO_BROADCAST
    -optval : int 类型的值,为1表示允许广播
    -optlen : optval的大小

3.服务端和客户端代码实现

3.1 server

#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>


int main()
{
    int udp_sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(udp_sockfd == -1)
    {
        perror("socket");
        exit(-1);
    }


    //设置广播
    int opt = 1;
    setsockopt(udp_sockfd,SOL_SOCKET,SO_BROADCAST,(const void*)&opt,sizeof(opt));

    //创建一个广播的地址
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = inet_addr("192.168.26.255"); //广播地址
    server.sin_port = htons(8000);

    
    int num = 0;
    while(1)
    {
        char sendBuf[128];
        sprintf(sendBuf,"hello,client-----%d\n",num++);
        //发送数据
        sendto(udp_sockfd,sendBuf,strlen(sendBuf)+1,0,
                (const struct sockaddr*)&server,sizeof(server));
        printf("广播数据:%s\n",sendBuf);
        sleep(1);
    }
    close(udp_sockfd);
    return 0;
}

3.2 client

#include <stdio.h>
#include <arpa/inet.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>


int main()
{
    int udp_sockfd = socket(AF_INET,SOCK_DGRAM,0);
    if(udp_sockfd == -1)
    {
        perror("socket");
        exit(-1);
    }

    //创建一个广播的地址
    struct sockaddr_in server;
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = INADDR_ANY; 
    server.sin_port = htons(8000);

    if(bind(udp_sockfd,(const struct sockaddr*)&server,sizeof(server)) == -1)
    {
        perror("bind");
        exit(-1);
    }

    char buf[128];
    while(1)
    {
        int num = recvfrom(udp_sockfd,buf,sizeof(buf),0,NULL,NULL);
        printf("server say: %s\n",buf);
    }
    close(udp_sockfd);
    return 0;
}


http://www.kler.cn/a/428196.html

相关文章:

  • 巴塞尔问题详解:计算所有正整数平方的倒数之和
  • .NET MAUI 入门学习指南
  • USB 3.1-GL3510-52芯片原理图设计
  • 内网穿透实现MC联机
  • PostgreSQL 约束
  • 【Super Tilemap Editor使用详解】(十三):快捷键指南(Keyboard Shortcuts)
  • 快速排序的基本思想和java实现
  • Next.js系统性教学:全面掌握客服务端组件(Server Components)
  • ARMv8-A MacOS调试环境搭建
  • Python毕业设计选题:基于大数据的淘宝电子产品数据分析的设计与实现-django+spark+spider
  • PyCharm文件、临时文件、目录、文件夹(Directory)、软件包(Package)的区别
  • Spring Boot配置文件敏感信息加密
  • 智创 AI 新视界 -- AI 与量子计算的未来融合前景(16 - 5)
  • python拆分Excel文件
  • docker安装ddns-go(外网连接局域网)
  • JVM 参数配置详细介绍
  • C++ Learning 函数重载•引用
  • PyTorch基本使用——张量的索引操作
  • opencv光流法推测物体的运动
  • Spring Boot日志:从Logger到@Slf4j的探秘
  • ChatGPT 最新推出的 Pro 订阅计划,具备哪些能力 ?
  • uniapp 微信小程序webview 和 h5数据通信
  • 【AWS re:Invent 2024】一文了解EKS新功能:Amazon EKS Auto Mode
  • Python实现BBS论坛自动签到【steamtools论坛】
  • Python 入门教程(2)搭建环境 | 2.4、VSCode配置Node.js运行环境
  • 如何利用DBeaver配置连接MongoDB和人大金仓数据库