LwIP RAW API 实现UDP多播收发

news2024/11/15 4:41:54

LwIP RAW API 实现UDP多播收发实现

1、初始化

static struct udp_pcb *multicast_pcb = NULL;
static ip_addr_t mutlcast_send_ip;
static ip_addr_t mutlcast_recv_ip;

static void udp_recv_multicast(void *arg, struct udp_pcb *pcb, struct pbuf *p,
    const ip_addr_t *addr, u16_t port);

static void udp_multicast_init(void)
{
    err_t err;

    if (multicast_pcb != NULL) return;

    multicast_pcb = udp_new();
    if (multicast_pcb == NULL)
    {
        LOG_LINE("udp_pcb申请失败");
        return;
    }

    IP4_ADDR(&mutlcast_send_ip, 239, 255, 255, 255);  /* 设置发送多播地址 */

    IP4_ADDR(&mutlcast_recv_ip, 239, 255, 255, 0);  /* 设置加入的多播接收地址 */

     /* 加入多播组 */
    err = igmp_joingroup(IP_ADDR_ANY, &mutlcast_recv_ip);
    if (err != ERR_OK)
    {
        LOG_LINE("加入多播组失败");
        goto free_udp_pcb;
    }

    err = udp_bind(multicast_pcb, IP_ADDR_ANY, 7770);   /* 绑定端口 */
    if (err != ERR_OK)
    {
        if (err == ERR_USE)
        {
            LOG_LINE("IP地址或端口已经被使用");
        }
        LOG_LINE("绑定IP、端口失败");
        goto free_udp_pcb;
    }

    udp_recv(multicast_pcb, udp_recv_multicast, NULL);
    
    LOG_LINE("组播初始化");
    return;
free_udp_pcb:
    udp_remove(multicast_pcb);
}

2、多播发送

int udp_multicast_send(const void *psrc, uint32_t src_len, uint16_t port)
{
    struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, src_len, PBUF_POOL);
    if (p == NULL)
    {
        LOG_LINE("pbuf申请失败");
        return -1;
    }
    pbuf_take(p, psrc, src_len);
    udp_sendto(multicast_pcb, p, &mutlcast_send_ip, port);
    pbuf_free(p);  /* 释放pbuf */
    return 0;
}

3、多播接收

static char recv_multicast_buf[1024] = {0};
void udp_recv_multicast(void *arg, struct udp_pcb *pcb, struct pbuf *p,
    const ip_addr_t *addr, u16_t port)
{
    struct pbuf *q;
    int recv_count = 0;
    struct ip4_addr_fmt {
        uint32_t addr1 : 8;
        uint32_t addr2 : 8;
        uint32_t addr3 : 8;
        uint32_t addr4 : 8;
    };

    for (q = p; q != NULL; q = p->next)
    {
        if (q->len > sizeof(recv_multicast_buf))
        {
            memcpy(recv_multicast_buf, q->payload, sizeof(recv_multicast_buf));
            LOG_LINE("数据溢出, 截断接收");
            return;
        }
        else 
        {
            if (recv_count < sizeof(recv_multicast_buf))
            {
                rt_memcpy(&recv_multicast_buf[recv_count], q->payload, q->len);
                recv_count += q->len;
            }
            else
            {
                LOG_LINE("数据溢出, 截断接收");
                return;
            }
        }
    }
    // uint32_t ip = addr->addr;
    struct ip4_addr_fmt *ip = (struct ip4_addr_fmt *)addr;
    LOG_LINE("multicast recv from %d.%d.%d.%d/%d, msg %s", 
            ip->addr1, ip->addr2, ip->addr3, ip->addr4, port, recv_multicast_buf);
}

通过UDP接收回调函数接收数据保存到buffer。
这里只是将接收的消息打印出来。

测试

组播发送测试:
打开网络调试助手,设置好监听端口号,板子程序通过什么端口号发送,这里就设置为相应的端口号。
在这里插入图片描述
前面初始化程序发送设置的多播组是239.255.255.255 ,往7777端口发送数据,所以这里设置端口号为7777

测试程序:

static char fmt_buf[10] = {0};
static uint16_t test_count = 0;
void btn_long_press_start(void *p_btn)
{
    struct Button *btn = (struct Button *)p_btn;
    switch (btn->button_id)
    {
        case BTN_ID_SYS_TEST:  /* 测试键 */

            break;
        case BTN_ID_CARD_OUT:  /* 强制退卡键 */
            rt_snprintf(fmt_buf, sizeof(fmt_buf), "test %d", ++test_count);
            udp_multicast_send(fmt_buf, rt_strlen(fmt_buf), 7777);
            LOG_LINE("退卡键长按 %s", fmt_buf);
            rt_memset(fmt_buf, 0, sizeof(fmt_buf));
            break;
        default:
            LOG_LINE("don't have this key");
            break;
    }
}

在这里插入图片描述
组播接收测试:
网络调试助手设置组播地址和远程地址、端口
在这里插入图片描述
板子程序接收数据加入的多播组是239.255.255.0,端口号是7770 ,IP地址是192.168.57.101

点击网络调试助手发送,串口调试助手打印出接收的数据
在这里插入图片描述

参考:

网络编程:用UDP通信实现组播通信(多播)_udp组播通信_qq_42343682的博客-CSDN博客

UDP局域网内广播消息_udp广播网段192.168.0.255_changeyourmind的博客

STM32F4板子使用LWIP进行组播收发数据的完整过程,附代码_lwip组播_纵横千里,捭阖四方的博客-CSDN博客

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

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

相关文章

安装cv2库时出现错误的一般解决方法

问题描述&#xff1a; 安装cv2库时出现错误 补充&#xff1a;cv2库的简单介绍 cv2是Python中常用的计算机视觉库OpenCV的Python接口模块。通过使用cv2模块&#xff0c;您可以方便地进行图像和视频的读取、处理和显示等操作。它提供了许多常用的图像处理函数和工具&#xff0…

WPF基础学习笔记3-文本控件

1.文本控件 文本控件System.Windows.Controls,TextBox继承自System.Windows.Controls.TextBoxBase类System.Windows.Controls.RichTextBox继承自System.Windows.Controls.TextBoxBase类 1.1 TextBox 表示一个控件&#xff0c;该控件可用于显示或编辑无格式文本 <Grid>&l…

Python算法练习6.17

leetcode 1768 交替合并字符串 给你两个字符串 word1 和 word2 。请你从 word1 开始&#xff0c;通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长&#xff0c;就将多出来的字母追加到合并后字符串的末尾。 返回 合并后的字符串 。 输入&#xff1a;word1 &qu…

【探索 Kubernetes|作业管理篇 系列 9】Pod 的服务对象

前言 大家好&#xff0c;我是秋意零。 在上一篇中&#xff0c;我们介绍了 Pod 的生命周期以及区分 Pod 字段的层次级别&#xff0c;相信你对此有了充分的认识。 今天&#xff0c;我们还会接着以 Pod 展开&#xff0c;说说它的 “服务对象”&#xff0c;一听就知道是对 Pod 提…

RocketMQ_高级功能

目录 一、消息存储 1、存储介质以及性能对比 2、消息的存储和发送 3、消息存储结构 4、刷盘机制 二、高可用性机制 1、消息消费高可用 2、消息发送高可用 3、消息主从复制 三、负载均衡 1、Producer负载均衡 2、Consumer负载均衡 四、消息重试 1、顺序消息的重试…

微信无人托管智能客服系统

随着人工智能技术的不断发展&#xff0c;大语言模型、智能客服、垂直化场景应用和微信聊天等三方终端系统已经成为了企业营销的重要工具。这些技术的结合可以帮助企业更好地与客户进行沟通&#xff0c;提高客户满意度和忠诚度&#xff0c;从而实现营销目标。 大语言模型可以帮…

Android:绘制自定义View人脸识别框

一.绘制矩形框实现 项目开发需要自定义View实现一个人脸框&#xff0c;代码实现很平常&#xff0c;一些细节记录一下&#xff0c;方便以后查阅。 代码实现&#xff1a; 1.1 自定义人脸识别框&#xff1a; FaceView.java package com.android.example.ui.view;import andro…

018:vue中自定义el-table 表头和单元格的样式

第018个 el-table 用于展示多条结构类似的数据&#xff0c;可对数据进行排序、筛选、对比或其他自定义操作。 vue在使用element UI table的是经常要用到的&#xff0c;由于原有的表头和单元格的样式不能满足项目的需要&#xff0c;需要自己来自定义样式。同时这里也做了个overf…

B/S版医院检验科lis系统源码 云lis系统

LIS系统为实验室服务对象提供检验申请、采集标本、结果查询等功能&#xff1b;为实验室工作人员的核收标本、分送标本、传送资料、分析前处理、质量控制、单向或双向通讯、分析后处理、结果审核、打印报告、结果查询等标本检测过程提供全面的技术支持。 .Net Core LIS系统源码…

python代码性能分析

基准测试可以发现程序变慢了&#xff0c;那么是因为什么原因导致性能变慢的&#xff0c;需要进一步做代码性能分析。python同样提供了性能分析工具。 cProfile cProfile是python默认的性能分析器&#xff0c;他只测量CPU时间&#xff0c;并不关心内存消耗和其他与内存相关联的…

逻辑越权之找回机制及接口安全(35)

会涉及到这三个内容 验证会涉及到&#xff0c;暴力测试&#xff0c;绕过测试 找回会涉及到&#xff0c;客户端回显&#xff0c;respponse状态值&#xff0c;找回流程绕过 接口会涉及到&#xff0c;调用便利 找回就像是忘记密码那种&#xff0c;然后会有验证&#xff0c;手机…

知识图谱实战应用16-知识图谱在化学物质结构上的应用,快速查找化学分子式与结构

大家好,我是微学AI,今天给大家介绍一下知识图谱实战应用16-知识图谱在化学物质结构上的应用,快速查找化学分子式与结构。在化学领域,知识图谱可以应用于化学物质结构上。化学物质结构主要指分子结构和化学键的组成情况。知识图谱可以将化学物质结构的相关数据以图谱的形式展…

oVirt 4.4.10三节点超融合集群安装配置及集群扩容(三)

本篇主要记录安装及使用过程中遇到的问题<包含4.4.x, 4.5.x> 设置engine管理页面可以通过IP访问ssh连接engine服务器并在/etc/ovirt-engine/engine.conf.d新建99-custom-sso-setup.conf,添加engine节点的IP或出口IPSSO_ALTERNATE_ENGINE_FQDNS="engine103.cluster.…

MySQL 索引与事务

MySQL 索引相关知识详解与事务的详解 一、索引的概念二、索引的作用索引的副作用 三、索引是如何实现的四、创建索引的原则依据五、索引的优缺点1、优点2、缺点 六、索引的分类和创建1、普通索引2、唯一索引3、主键索引4、组合索引5、全文索引 七、索引的查看八、索引的删除1、…

操作系统2:进程的描述与控制

目录 1、什么是前驱图&#xff1f; 2、进程的定义和描述 &#xff08;1&#xff09;什么是进程&#xff1f; &#xff08;2&#xff09;进程的基本状态及转换 &#xff08;3&#xff09;挂起操作和进程状态的转换 3、进程管理中的数据结构 &#xff08;1&#xff09;进程…

楼宇照明系统在图书馆的应用介绍 安科瑞 许敏

【摘要】EIB总线作为楼宇家居自动化控制技术的主流&#xff0c;具有适应性好、功能强大与可靠性高等多方面优点&#xff0c;能很 好地满足定时、合成照度、人体检测和手控等不同的照明控制需求。通过智能化的自动控制实现了楼宇的舒适照 明和节能照明两大目标&#xff0c;克服传…

一、DSMP/OLS等夜间灯光数据贫困地区识别——理论

一、前言 对于贫困的定量研究,前人多实用传统的社会经济统计数据构建模型,但是该数据存在统计口径多源、样本获取受限等不足,不能较好的反映区域贫困的时间按序列编号。随着遥感技术的不断发展,DMSP/OLS等夜间灯光数据的广泛应用为了大范围、动态的区域贫困监测提供一种新…

c++系列之string类的常用接口函数

&#x1f497; &#x1f497; 博客:小怡同学 &#x1f497; &#x1f497; 个人简介:编程小萌新 &#x1f497; &#x1f497; 如果博客对大家有用的话&#xff0c;请点赞关注再收藏 &#x1f31e; string string时表示字符串的字符类 //使用 string类包含#include 头文件 以及…

基于Java人事管理信息系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a; ✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战 ✌ &#x1f345; 文末获取源码联系 &#x1f345; &#x1f447;&#x1f3fb; 精…