SylixOS下UDP组播测试程序

news2024/11/24 12:59:09

SylixOS下UDP组播测试

测试效果截图如下:
在这里插入图片描述

在这里插入图片描述

udp组播发送测试程序。

/*********************************************************************************************************
**
**                                    中国软件开源组织
**
**                                   嵌入式实时操作系统
**
**                                SylixOS(TM)  LW : long wing
**
**                               Copyright All Rights Reserved
**
**--------------文件信息--------------------------------------------------------------------------------
**
** 文   件   名: umc_send.c
**
** 创   建   人: Hou.JinYu (侯进宇)
**
** 文件创建日期: 2024 年 06 月 05 日
**
** 描        述: udp multicast send test program
*********************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#include <netdb.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
/*********************************************************************************************************
** 名称: getInaddr_s2v
** 功能: 将字符串网络地址转为数值型网络地址
** 输入: pAddrString     字符串网络地址
** 输出: 数值型网络地址
*********************************************************************************************************/
struct sockaddr_in  getInaddr_s2v (CHAR  *pAddrString)
{
    in_addr_t   in_addr;
    in_port_t   in_port;
    CHAR        in_string[32];
    CHAR       *pcPtr;
    struct sockaddr_in addr = {0, AF_INET, 0, {INADDR_ANY}};


    if (pAddrString == NULL) {
        return  (addr);
    }

    strncpy(in_string, pAddrString, sizeof(in_string) - 1);

    pcPtr = strchr(in_string, ':');
    if (pcPtr == NULL) {
        return  (addr);
    }
    *pcPtr = '\0';

    in_addr = inet_addr(in_string);
    if (IPADDR_NONE == in_addr) {
        return  (addr);
    }

    in_port = strtoul(pcPtr + 1, NULL, 10);
    if (in_port == 65535) {
        return  (addr);
    }

    memset(&addr, 0, sizeof(addr));
    addr.sin_family      = AF_INET;
    addr.sin_addr.s_addr = in_addr;
    addr.sin_port        = htons(in_port);

    return  (addr);
}
/*********************************************************************************************************
** 名称: main
** 功能: 入口函数
** 输入: argc   参数个数
**       argv   参数列表
** 输出: 错误号
*********************************************************************************************************/
int main (int argc, char *argv[])
{
    int                sock;
    int                iLoop = 0;
    struct ip_mreq     mreq;
    struct sockaddr_in selfaddr  = {0, AF_INET, 0, {INADDR_ANY}};
    struct sockaddr_in groupaddr = {0, AF_INET, 0, {INADDR_ANY}};


    if (argc == 1) {
        printf("umc_send groupaddr [selfaddr]\n");
        return  (0);
    }

    if (argc > 1) {
        groupaddr = getInaddr_s2v(argv[1]);
    }

    if (argc > 2) {
        selfaddr = getInaddr_s2v(argv[2]);
    }

    if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
        perror("Socket creation failed");
        return  (0);
    }

    if (argc > 2) {
        if (bind(sock, (struct sockaddr *)&selfaddr, sizeof(selfaddr)) < 0) {
            perror("bind failed");
            close(sock);
            return  (0);
        }
    }

    if (setsockopt(sock, IPPROTO_IP, IP_MULTICAST_LOOP, &iLoop,sizeof(iLoop)) < 0) {
        printf("setsockopt error!\n");
        close(sock);
        return  (0);
    }

    mreq.imr_multiaddr.s_addr = groupaddr.sin_addr.s_addr;
    mreq.imr_interface.s_addr = selfaddr.sin_addr.s_addr;
    if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
        perror("setsockopt IP_ADD_MEMBERSHIP failed");
        close(sock);
        return  (0);
    }

    while (1) {
        const char *message = "udp multicast send test!";

        if (sendto(sock, message, strlen(message), 0, (struct sockaddr *)&groupaddr, sizeof(groupaddr)) < 0) {
            perror("Sending data failed");
        } else {
            printf("udp send test ok\n");
        }
        sleep(1);
    }

    close(sock);

    return  (0);
}
/*********************************************************************************************************
  END
*********************************************************************************************************/

udp组播接收测试程序。

/*********************************************************************************************************
**
**                                    中国软件开源组织
**
**                                   嵌入式实时操作系统
**
**                                SylixOS(TM)  LW : long wing
**
**                               Copyright All Rights Reserved
**
**--------------文件信息--------------------------------------------------------------------------------
**
** 文   件   名: umc_recv.c
**
** 创   建   人: Hou.JinYu (侯进宇)
**
** 文件创建日期: 2024 年 06 月 05 日
**
** 描        述: udp multicast recv test program
*********************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#include <netdb.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
/*********************************************************************************************************
** 名称: getInaddr_s2v
** 功能: 将字符串网络地址转为数值型网络地址
** 输入: pAddrString     字符串网络地址
** 输出: 数值型网络地址
*********************************************************************************************************/
struct sockaddr_in  getInaddr_s2v (CHAR  *pAddrString)
{
    in_addr_t   in_addr;
    in_port_t   in_port;
    CHAR        in_string[32];
    CHAR       *pcPtr;
    struct sockaddr_in addr = {0, AF_INET, 0, {INADDR_ANY}};


    if (pAddrString == NULL) {
        return  (addr);
    }

    strncpy(in_string, pAddrString, sizeof(in_string) - 1);

    pcPtr = strchr(in_string, ':');
    if (pcPtr == NULL) {
        return  (addr);
    }
    *pcPtr = '\0';

    in_addr = inet_addr(in_string);
    if (IPADDR_NONE == in_addr) {
        return  (addr);
    }

    in_port = strtoul(pcPtr + 1, NULL, 10);
    if (in_port == 65535) {
        return  (addr);
    }

    memset(&addr, 0, sizeof(addr));
    addr.sin_family      = AF_INET;
    addr.sin_addr.s_addr = in_addr;
    addr.sin_port        = htons(in_port);

    return  (addr);
}
/*********************************************************************************************************
** 名称: main
** 功能: 入口函数
** 输入: argc   参数个数
**       argv   参数列表
** 输出: 错误号
*********************************************************************************************************/
int main (int argc, char *argv[])
{
    int                sock;
    int                optval = 1;
    socklen_t          fromlen;
    struct ip_mreq     mreq;
    struct sockaddr_in selfaddr  = {0, AF_INET, 0, {INADDR_ANY}};
    struct sockaddr_in groupaddr = {0, AF_INET, 0, {INADDR_ANY}};
    struct sockaddr_in fromaddr  = {0, AF_INET, 0, {INADDR_ANY}};

    if (argc < 3) {
        printf("umc_recv groupaddr selfaddr\n");
        return  (0);
    }

    groupaddr = getInaddr_s2v(argv[1]);
    selfaddr  = getInaddr_s2v(argv[2]);
    selfaddr.sin_port = groupaddr.sin_port;

    if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
        perror("Socket creation failed");
        return  (0);
    }

    if (bind(sock, (struct sockaddr *)&selfaddr, sizeof(selfaddr)) < 0) {
        perror("bind failed");
        close(sock);
        return  (0);
    }

    // 设置地址重用,可选,用于在同一台机器上的多个进程接收同一组播流。否则同一时刻只能有一路socket能收到组播。
    if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) {
        perror("setsockopt SO_REUSEADDR failed");
        close(sock);
        return  (0);
    }

    // 加入组播组
    mreq.imr_multiaddr.s_addr = groupaddr.sin_addr.s_addr;
    mreq.imr_interface.s_addr = selfaddr.sin_addr.s_addr;
    if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
        perror("setsockopt IP_ADD_MEMBERSHIP failed");
        close(sock);
        return  (0);
    }

    while (1) {
        ssize_t len;
        char    buf[2048];

        fromlen = sizeof(fromaddr);
        len = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *)&fromaddr, &fromlen);
        if (len < 0) {
            perror("recvfrom failed");
            break;
        }
        buf[len] = '\0';
        printf("recv %d byte from %s:%d : %s\n",
                (INT)len, inet_ntoa(fromaddr.sin_addr), ntohs(fromaddr.sin_port), buf);
    }

    // 离开组播组,通常在程序退出前执行
    if (setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, &mreq, sizeof(mreq)) < 0) {
        perror("setsockopt IP_DROP_MEMBERSHIP failed");
    }

    close(sock);

    return  (0);
}
/*********************************************************************************************************
  END
*********************************************************************************************************/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1821479.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

华为wlan实验

分为三步&#xff1a;1、网络互通&#xff0c;2、AP上线&#xff0c;3、wlan业务 1、网络互通 crow-sw: vlan batch 20 100 dhcp enable int vlan 20 ip add 192.168.20.1 24 dhcp select interfaceinterface GigabitEthernet0/0/2port link-type accessport default vlan 100…

构建 LLM 应用为什么需要文本加载器,langchain 中如何使用文本加载器?

构建 LLM 应用为什么需要文本加载器&#xff0c;langchain 中如何使用文本加载器&#xff1f; 上一篇文章中 [使用langchain搭建本地知识库系统(新) 我们构建一个 RAG 的本地应用&#xff0c;我们使用到了网页的文本加载器用来动态获取网页的数据。 在不同的应用场景中需要使…

【Spine学习07】之跑步动作制作思路总结

前几节试着做了待机和走路动画 现在开始尝试做跑步动作 注意跑步动作和走路一样 暂时不需要使用IK约束但是会用到塞贝尔曲线&#xff08;模拟裙子飞起动效&#xff09; 第一步&#xff1a; 先将人物整体斜放置&#xff08;因为人跑步的时候&#xff0c;身体前倾&#xff09; …

速度与激情:解锁8款免费文件传输利器,让大数据秒传成为可能

以下是8个免费高速文件传输工具的推荐&#xff0c;这些工具可以帮助您彻底告别数据线&#xff0c;使文件传输更加便捷和高效&#xff1a; 1、百度网盘 特点&#xff1a;云存储和共享应用&#xff0c;支持多种形式的文件存储和分享&#xff0c;提供大容量的免费存储空间。 适用…

力扣每日一题(2024-06-14)2786. 访问数组中的位置使分数最大

参考官方题解2786. 访问数组中的位置使分数最大 - 力扣&#xff08;LeetCode&#xff09; 问题描述 给定一个下标从 0 开始的整数数组 nums 和一个正整数 x。你一开始在数组的第 0 个位置&#xff0c;你可以移动到满足 i < j 的任意位置 j。如果你访问的位置 i&#xff0c…

毕业生季,你的校园卡开始注销了吗?

​ 毕业季&#xff0c;好多朋友们已经走出校园了&#xff0c;换了一个新的城市接着工作了&#xff0c;那么&#xff0c;之前办理的校园卡你都是怎么处理的&#xff1f; 其实&#xff0c;校园卡就是为了方便校园生活而推出的一种卡&#xff0c;在学校期间可能比较优惠&#xff…

企业薪酬体系的搭建

随着企业的逐步发展&#xff0c;其人力资源管理方面的问题也逐渐显露出来&#xff0c;诸如职责不清、相互推卸责任、员工工作积极性较低等问题&#xff0c;这些管理上的问题导致产品质量不断下降&#xff0c;客户投诉率也不断上升&#xff0c;且优秀人员的流失率也有增加的趋势…

沃沃阀门×蓝卓 | 再度携手!数字化车间项目启动会顺利召开

6月13日&#xff0c;蓝卓与沃沃阀门数字化车间项目正式启动&#xff0c;依托蓝卓supOS工业操作系统&#xff0c;打造统一数字化底座&#xff0c;助推沃沃阀门物料自动配送、产销高效协同、设备全面管理、车间可视化管理等目标实现。 丽水莲都区经信局副局长李军舫、区经信局信…

Arco-design <a-range-picker> 快捷键日期点击后不关闭面板

需求&#xff1a;点击快捷日期&#xff0c;面板预览日期&#xff0c;点击确定后触发事件 思路&#xff1a;手动控制面板开启和关闭&#xff0c;点击input时开启&#xff0c;点击面板确定或除input和面板的其他位置时关闭面板 <a-range-pickerid"input"v-model&quo…

学习理解 CompletableFuture

学习理解 CompletableFuture CompletableFuture 是 Java 8 引入的一个强大的工具&#xff0c;它使得编写异步和并行代码变得更加容易。 CompletableFuture 是 java.util.concurrent 包的一部分&#xff0c;是 Future 的扩展&#xff0c;它不仅允许你手动完成计算&#xff0c;还…

锂电池航空运输报告办理 UN38.3电池报告

锂电池航空运输报告办理 锂电池航空运输报告&#xff0c;通常指的是UN38.3测试报告&#xff0c;这是联合国针对危险品运输制定的《联合国危险物品运输试验和标准手册》的第3部分38.3款的要求。UN38.3测试报告证明锂电池在运输过程中的安全性&#xff0c;包括高度模拟、高低温循…

Liquibase(Oracle SQLcl集成版)简明示例

本文使用的是Oracle SQLcl中集成的Liquibase&#xff0c;而非开源版Liquibase。 Liquibase的快速入门可以参见Liquibase Core Concepts。需要了解一下概念&#xff1a; Change log&#xff1a;基于文本的更改日志文件按顺序列出对数据库所做的所有更改Change set&#xff1a;…

Python学习之旅:你的大学计算机专业宝藏路线图

在信息时代的浪潮中&#xff0c;Python以其强大的功能和极简的语法成为了无数程序员心中的白月光。作为大学计算机专业的学生&#xff0c;掌握Python不仅能够为未来的职业生涯铺路&#xff0c;更能让您在学术研究和实际应用中如鱼得水。今天&#xff0c;我将与大家分享一套实用…

Vue3-滑动到最右验证功能

1、思路 1、在登录页面需要启动向右滑块验证 2、效果图 3、文章地址&#xff1a;滑动验证码的实现-vue-simple-verify 2、成分分析 1、由三块构成&#xff0c;分别是底部条、拖动条、拖动移动部分 2、底部条&#xff1a;整体容器&#xff0c;包括背景、边框和文字&#xf…

人工智能的研究方向

人工智能的应用、技术与基础研究方向 人工智能&#xff08;AI&#xff09;的发展已经渗透到社会的每一个角落&#xff0c;从自动驾驶汽车到智能语音助手&#xff0c;从图像识别到疾病诊断&#xff0c;AI技术正在重塑我们的工作和生活方式。为了更好地理解这一领域的广泛性和深度…

管理十大定律:深度解析与实际应用

在复杂多变的企业管理环境中&#xff0c;掌握并运用一些基本的定律和规律&#xff0c;对于提升管理效率、优化资源配置具有至关重要的作用。 1、马太效应 定律解析&#xff1a;马太效应描述了资源分配中的一种累积优势现象&#xff0c;即强者愈强&#xff0c;弱者愈弱。这源…

53.Python-web框架-Django开始第一个应用的多语言

针对上一篇的功能&#xff0c;本次仅对页面做了多语言&#xff0c;大家可以看看效果。 51.Python-web框架-Django开始第一个应用的增删改查-CSDN博客 目录 部门列表 新增部门 编辑部门 部门列表 源码 <!DOCTYPE html> {% load static %} {% load i18n %} <html …

RAG 实践-Ollama+AnythingLLM 搭建本地知识库

什么是 RAG RAG&#xff0c;即检索增强生成&#xff08;Retrieval-Augmented Generation&#xff09;&#xff0c;是一种先进的自然语言处理技术架构&#xff0c;它旨在克服传统大型语言模型&#xff08;LLMs&#xff09;在处理开放域问题时的信息容量限制和时效性不足。RAG的…

wmv转换mp4怎么操作?3个格式转换方法分享

wmv转换mp4怎么操作&#xff1f;将WMV转换为MP4格式&#xff0c;可以方便我们在多种设备和平台上流畅播放视频。MP4格式具有广泛的兼容性和优化过的编码&#xff0c;使其在各种媒体播放器、智能手机、平板电脑以及电视上都能得到良好的支持。此外&#xff0c;MP4格式的视频文件…

12.1 Go 测试的概念

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…