[UDP] UDP广播的实现IPv4&IPv6

这篇具有很好参考价值的文章主要介绍了[UDP] UDP广播的实现IPv4&IPv6。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

简介

写了一个UDP广播的代码。
IPv4一个,IPv6一个。
编译环境是linux C++11。

文件构成

ser.cpp用于发送广播。
cli.cpp用于接收广播。

build_cli.sh和build_svr.sh是编译脚本。

./cli 等待接收广播数据
./svr 执行发送广播

代码实现

IPv4, 发送广播

//使用的广播地址是"255.255.255.255",路由不会转发

int UDP_Controler::BroadCast()
    {
        if (m_ctl_type != ctl_unknowtype && m_ctl_type != ctl_broadcast_send)
        {
            LOGS << "Type error" << LOGE;
            return -1;
        }
        int iset = 1;
        if (setsockopt(m_local_fd, SOL_SOCKET, SO_BROADCAST, &iset, sizeof(iset)))
        {
            perror("setsockopt");
            return -1;
        }

        char buff[MIN_BUFFSISE] = {0x00};
        sprintf(buff, "%s", "@TEST GETJOB \r\n");

        sockaddr_in addr;
        addr.sin_family = AF_INET;
        addr.sin_addr.s_addr = inet_addr("255.255.255.255");
        addr.sin_port = htons(9100);
        int res = sendto(m_local_fd, buff, strlen(buff), 0,
                         (sockaddr *)&addr, sizeof(addr));
        if (res == -1)
        {
            perror("sendto");
            return -1;
        }
        LOGS << "send broadcast msg:" << buff << "." << LOGE;
        m_ctl_type = ctl_broadcast_send;
        return 0;
    }

IPv4, 接收广播

//使用的广播地址是"255.255.255.255",路由不会转发

int UDP_Controler::BroadCast_Recv()
    {
        if (m_ctl_type != ctl_unknowtype && m_ctl_type != ctl_broadcast_recv)
        {
            LOGS << "Type error" << LOGE;
            return -1;
        }

        char buff[MIN_BUFFSISE] = {0x00};
        sockaddr_in local_addr, addr;
        socklen_t len = sizeof(sockaddr_in);
        local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
        local_addr.sin_port = htons(9100);
        local_addr.sin_family = AF_INET;

        if(bind(m_local_fd, (sockaddr*)&local_addr, len) == -1) {
            perror("bind");
            return -1;
        }

        int res = recvfrom(m_local_fd, buff, MIN_BUFFSISE, 0,
                           (sockaddr *)&addr, &len);
        if (res == 0)
        {
            perror("recvfrom return 0");
            return -1;
        }
        else if (res == -1)
        {
            perror("recvfrom return -1");
            return -1;
        }
        LOGS << "recv broadcast msg:" << buff << ",from:" << inet_ntoa(addr.sin_addr) << ":" << ntohs(addr.sin_port) << LOGE;
            
        m_ctl_type = ctl_broadcast_recv;
        return res;
    }

IPv6 ,发送广播

//唯有sockaddr 部分和IPv4不同
// "FF02::1"是IPv6链路本地广播地址,不可跨越路由器

int UDP_Controler::BroadCast()
    {
        if (m_ctl_type != ctl_unknowtype && m_ctl_type != ctl_broadcast_send)
        {
            LOGS << "Type error" << LOGE;
            return -1;
        }
        int iset = 1;
        if (setsockopt(m_local_fd, SOL_SOCKET, SO_BROADCAST, &iset, sizeof(iset)))
        {
            perror("setsockopt");
            return -1;
        }

        char buff[MIN_BUFFSISE] = {0x00};
        sprintf(buff, "%s", "FF02::1");

        sockaddr_in6 addr;
        addr.sin6_family = AF_INET6;
        int res = inet_pton(AF_INET6, buff, &addr.sin6_addr);
        if(res <= 0) {
            perror("inet_pton");
            return -1;
        }
        addr.sin6_port = htons(9100);
        addr.sin6_scope_id = if_nametoindex("ens33");

        bzero(buff,MIN_BUFFSISE);
        sprintf(buff, "%s", "@TEST IPV6 GETJOB \r\n");
        res = sendto(m_local_fd, buff, strlen(buff), 0,
                         (sockaddr *)&addr, sizeof(addr));
        if (res == -1)
        {
            perror("sendto");
            return -1;
        }
        LOGS << "send broadcast msg:" << buff << "." << LOGE;
        m_ctl_type = ctl_broadcast_send;
        return 0;
    }

IPv6, 接收广播

//唯有sockaddr 不分和IPv4不同
// "FF02::1"是IPv6链路本地广播地址,不可跨越路由器

 int UDP_Controler::BroadCast_Recv()
    {
        if (m_ctl_type != ctl_unknowtype && m_ctl_type != ctl_broadcast_recv)
        {
            LOGS << "Type error" << LOGE;
            return -1;
        }

        char buff[MIN_BUFFSISE] = {0x00};
        sockaddr_in6 local_addr, addr;
        socklen_t len = sizeof(sockaddr_in6);
        local_addr.sin6_addr = in6addr_any;
        local_addr.sin6_port = htons(9100);
        local_addr.sin6_family = AF_INET6;

        if(bind(m_local_fd, (sockaddr*)&local_addr, len) == -1) {
            perror("bind");
            return -1;
        }

        int res = recvfrom(m_local_fd, buff, MIN_BUFFSISE, 0,
                           (sockaddr *)&addr, &len);
        if (res == 0)
        {
            perror("recvfrom return 0");
            return -1;
        }
        else if (res == -1)
        {
            perror("recvfrom return -1");
            return -1;
        }
        char addrv6[128] = { 0x00 };
        inet_ntop(AF_INET6, &addr.sin6_addr , addrv6, 128 );
        LOGS << "recv broadcast msg:" << buff << ",from:" << addrv6 << ":" << ntohs(addr.sin6_port) << LOGE;
            
        m_ctl_type = ctl_broadcast_recv;
        return res;
    }

完整代码:
查看链接资源。文章来源地址https://www.toymoban.com/news/detail-806741.html

到了这里,关于[UDP] UDP广播的实现IPv4&IPv6的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Qt网络编程 (udp广播和接收例)

    使用两个项目 1 sender 用来广播\\\"hello world\\\"; 2 receiver 用来接收广播信息 1 创建Qdialog类 2 在sender.pro 中添加 QT +=network 一行代码 3 在sender.h 中声明类 class QUdpSocket; 在声明一个私有对象 QUdpSocket *sender; 4 在ui界面拖入一个按钮 用来触发广播信息 其槽函数如下 在sender.cpp 构造函数中添

    2024年02月11日
    浏览(15)
  • 【嵌入式-网络编程】vmware中使用UDP广播失败问题

    问题描述: 自己在vmware中搭建了2台虚拟机,虚拟机A向虚拟机A和虚拟机B发送广播信息,接收端在虚拟机A和虚拟机B,这个时候,由于没配置 sin.sin_addr.s_addr = htonl(INADDR_ANY); ,而是配置的 inet_pton(AF_INET, SERV_IP, sin.sin_addr.s_addr); ,导致虚拟机A的广播信号发出去了,但是虚拟机B和

    2024年01月23日
    浏览(23)
  • IPv4网络用户访问IPv6网络服务器

    NAT64静态映射为一对一的对应关系,通常应用在IPv4网络主动访问IPv6网络的场景中。  要求位于IPv4网络中的PC通过IPv4地址1.1.1.10能够直接访问位于IPv6网络中Server。 操作步骤 配置FW。 # 配置接口GigabitEthernet 0/0/1的IPv4地址。 # 开启IPv6报文转发功能。 # 配置接口GigabitEthernet 0/0/2的

    2024年02月06日
    浏览(19)
  • 【计算机网络-网络层】IPv4 和 IPv6

    1.1 IP 数据报格式 IP 数据报的格式如下: 首部(发送在前) 数据部分 固定部分(20B)+ 可变部分 数据信息 IP 数据报首部的格式如下: IP 首部 的字段含义如下: 版本(4b) :IP 协议版本,广泛使用的版本号为 4。 首部长度(4b,单位 4B) :可表示的最小十进制为 5,最大十

    2023年04月16日
    浏览(23)
  • IPv4 与 IPv6:网络性能和带宽的比较

    网络连接已经成为我们生活中不可或缺的一部分,而IP地址是网络连接中最基本和最重要的部分。IPv4和IPv6是两种常用的IP地址协议,它们之间有着很大的差异。 首先,让我们了解一下IPv4和IPv6的基本概念。 IPv4是互联网上使用最广泛的IP地址协议,它使用32位地址来标识网络中

    2024年02月17日
    浏览(19)
  • 【计算机网络:自顶向下方法】(四)网络层 (IPV4 | IPV6 | 路由算法 )

    【计算机网络:自顶向下方法 第7版 | 中科大 】 网络层服务 网络层功能 : 转发: 将分组从路由器 的输入接口转发到合适 的输出接口 (局部) 路由: 使用路由算法来 决定分组从发送主机到 目标接收主机的路径 (全局 ) 路由选择算法 路由选择协议  本地,每个路由

    2024年02月02日
    浏览(32)
  • Android 12(S) IPV4优先IPV6(优先使用IPv4地址)的实现

    根据RFC 6724中 规定 android 会优先选择IPv6 地址而不是 IPv4 地址,当整个网络中,同时支持IPv4和IPv6 地址时,设备中的应用请求服务器DNS时,会优先返回IPv6地址。 假如IPv6服务器支持内容不够完善,则应用显示内容会与IPv4服务器不一致,甚至有问题。 因此有需求是定制设备平

    2024年02月03日
    浏览(23)
  • 【计算机网络:自顶向下方法】(四)网络层 : 数据平面 (IPV4 | IPV6 | 路由算法 )

    【计算机网络:自顶向下方法 第7版 | 中科大 】 网络层服务 网络层功能 : 转发: 将分组从路由器 的输入接口转发到合适 的输出接口 (局部) 路由: 使用路由算法来 决定分组从发送主机到 目标接收主机的路径 (全局 ) 路由选择算法 路由选择协议  本地,每个路由

    2024年02月09日
    浏览(24)
  • 家用宽带公网ipv4/ipv6搭建服务(常见两种网络模式)超详细

    静态内网IP,动态内网IP,公网IP,DNS,DHCP,DMZ,UPNP,路由,桥接,DDNS (一)目的与概念介绍 目的: 将局域网内的一台主机的服务共享到公网(互联网)上被访问,提供服务。 前提: 该宽带(顶级路由)具有公网ip,否则都在内部局域网访问 概念介绍: 静态内网ip:即再

    2024年02月11日
    浏览(22)
  • 软考系分之计算机网络IP地址的表示(IPv4及IPv6)

      本篇介绍计算机网络中的IP地址,在网络工程师的考试中,IP地址是必考内容,但是在系统分析师的考察中,IP地址的考查重点,应该就是IPv4和IPv6的相关概念和IPv4中简单的子网划分计算了。 2.1 IPv4分类表示   IP地址中,机器存放IPv4是32位二进制代码,每隔8位插一个空格

    2024年01月18日
    浏览(21)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包