LwIP RAW API 实现UDP多播收发

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博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

结构化GPT用例,在CSDN私密社区中死磕@ada 探索SpringBoot

在CSDN私密社区中死磕ada 探索SpringBoot Q: Spring的核心概念是哪些&#xff1f;Q: Spring MVC的核心概念是哪些&#xff1f;Q: SpringBoot的核心概念有哪些&#xff1f;Q: 介绍下SpringBoot AutoConfiguration的机制。Q: SpringBootConfiguration 和 Configuration 的区别是&…

C# 学习(一)概述

今天开始学习 C#&#xff0c;所有学习资料来源于&#xff1a; 菜鸟教程 一、C# 简介 C# 是 .NET 框架的一部分&#xff0c;随之创造出来的语言&#xff0c;所以了解 C# 前&#xff0c;需要知道 .NET 是个什么东西。 1.1 .NET 框架介绍 .NET 是微软提出的 Web 的一种软件开发…

【每日一题】LCP 41. 黑白翻转棋

【每日一题】LCP 41. 黑白翻转棋 LCP 41. 黑白翻转棋题目描述解题思路 LCP 41. 黑白翻转棋 题目描述 在 n*m 大小的棋盘中&#xff0c;有黑白两种棋子&#xff0c;黑棋记作字母 “X”, 白棋记作字母 “O”&#xff0c;空余位置记作 “.”。当落下的棋子与其他相同颜色的棋子在…

JavaScript ES10新特性

文章目录 导文Array.prototype.flat()和Array.prototype.flatMap()Object.fromEntries()String.prototype.trimStart()和String.prototype.trimEnd()格式化数字动态导入可选的catch绑定BigIntglobalThis 导文 JavaScript ES10&#xff0c;也被称为ES2019&#xff0c;引入了一些…

【07】STM32·HAL库开发-新建寄存器版本MDK工程 |下载STM32Cube固件包 | 新建MDK工程步骤

目录 1.新建工程前的准备工作&#xff08;了解&#xff09;1.1下载相关STM32Cube 官方固件包&#xff08;F1/F4/F7/H7) 2.新建寄存器版本MDK工程步骤&#xff08;熟悉&#xff09;2.1新建工程文件夹2.1.1Drivers文件夹2.1.2Middlewares文件夹2.1.3Output文件夹2.1.4Projects文件…

SpringMvc学习——在idea中新建springWeb项目 浏览器请求 和 服务器响应 SpringMvc文件相关

目录 引出基础知识&#xff1a;三层架构和MVC1. 三层架构2.MVC模型 springWeb项目IDEA搭建1.新建一个普通的maven项目2.导入包&#xff0c;pom.xml文件3.写主启动类Main.java文件SpringBootApplication4.写application.yml文件spring的配置文件5.启动&#xff0c;运行main.java…

Spark大数据处理学习笔记(3.8.3) Spark RDD典型案例-利用RDD实现分组排行榜

该文章主要为完成实训任务&#xff0c;详细实现过程及结果见【http://t.csdn.cn/Twpwe】 文章目录 一、任务目标二、准备工作2.1 在本地创建成绩文件2.2 将成绩文件上传到HDFS上指定目录 三、完成任务3.1 在Spark Shell里完成任务3.1.1 读取成绩文件得到RDD3.1.2 利用映射算子生…

Spring Cloud Alibaba Seata(一)

目录 一、Seata 1、分布式事务简介 1.1、分布式事务理论 1.2、分布式事务解决方案 2、Seata简介 3、Seata安装 一、Seata 1、分布式事务简介 基础概念&#xff1a;事务ACID A&#xff08;Atomic&#xff09;&#xff1a;原子性&#xff0c;构成事务的所有操作&#xf…

27-2BP_Adaboost强分类器公司财务预管建模——强分类器和弱分类器(附matlab程序)

1.简述 Adaboost算法的思想是合并多个“弱”分类器的输出以产生有效分类。其主要步骤为&#xff1a;首先给出弱学习算法和样本空间&#xff08;x,y&#xff09;&#xff0c;从样本空间中找出m组训练数据&#xff0c;每组训练数据的权重都是1/m。然后用弱学习算法迭代运算T次&am…

爬虫小白应该如何学习爬虫

什么是Python3网络爬虫&#xff1f; 定义&#xff1a; 网络爬虫&#xff08;Web Spider&#xff09;&#xff0c;又被称为网页蜘蛛&#xff0c;是一种按照一定的规则&#xff0c;自动地抓取网站信息的程序或者脚本。爬虫其实是通过编写程序&#xff0c;模拟浏览器上网&#x…

Flutter 库:强大的工具及扩展——nb_utils

Flutter 库&#xff1a;强大的工具及扩展——nb_utils 文章目录 Flutter 库&#xff1a;强大的工具及扩展——nb_utils一、概述1、简介2、功能3、官方资料 二、基本使用1、安装2、基本使用第一步&#xff1a;在 main.dart 中初始化第二步&#xff1a;在您的 MaterialApp 或 Cup…

SpringBoot中@ControllerAdvice的三种使用场景

一、全局异常处理 代码示例如下: /*** author qinxun* date 2023-06-14* Descripion: 业务层异常枚举*/ public enum ServiceExceptionEnum {SUCCESS(0, "成功"),ERROR(1, "失败"),SYS_ERROR(1000, "服务端发生异常"),MISSING_REQUEST_PARAM_E…

微信小程序自定义模块

自定义wxs并引入 新建一个tools.wxs 创建一些function,并使用moule.exports {}导出 使用 <wxs>标签 并填写正确src 书写module名称 之后在其他标签内&#xff0c;使用 {{自定的module名称.自定义的一个function并传入对应参数}}就可以实现参数在自定义function中的导入…

用docker搭建selenium grid分布式环境实践

目录 前言&#xff1a; selenium jar包直接启动节点 用docker命令直接启动 docker-compose 启动 Hub和node在一台机器上 Hub和node不在一台机器上 遗留问题 总结 前言&#xff1a; Selenium是一个流行的自动化测试工具&#xff0c;支持多种编程语言和多种浏览器。Sele…

SpringCloudAlibaba之Sentinel源码分析--protoc-3.17.3-win64

Sentinel源码分析 文章目录 Sentinel源码分析1.Sentinel的基本概念1.1.ProcessorSlotChain1.2.Node1.3.Entry1.3.1.自定义资源1.3.2.基于注解标记资源 1.4.Context1.4.1.什么是Context1.4.2.Context的初始化1.4.2.1.自动装配1.4.2.2.AbstractSentinelInterceptor1.4.2.3.Contex…

【linux kernel】linux media子系统分析之media控制器设备

文章目录 一、抽象媒体设备模型二、抽象媒体设备三、Entity四、Interfaces五、Pad六、Link七、Media图遍历八、使用计数和电源处理九、link设置十、Pipeline和Media流十一、链接验证十二、媒体控制器设备的分配器API 本文基于linux内核 4.19.4&#xff0c;抽象媒体设备模型框架…

chatgpt赋能python:Python如何查找特定名称文件

Python如何查找特定名称文件 在计算机文件管理和互联网网络应用程序中&#xff0c;查找特定文件往往是一项必要的任务。在使用Python编程时&#xff0c;我们可以使用Python内置的os模块来查找特定名称的文件。本文将介绍如何使用Python查找特定名称的文件&#xff0c;并提供实…

013:解决vue中不能加载.geojson的问题

第013个 查看专栏目录: VUE — element UI 本文章目录 问题状态造成这个结果的原因&#xff1a;解决办法Vue Loader 其他特性&#xff1a;专栏目标 问题状态 在做vue项目的时候&#xff0c;碰到这样一个问题&#xff0c;vue页面中引用一个.geojson文件&#xff0c;提示如下错误…

【C++篇】字符串:标准库string类

友情链接&#xff1a;C/C系列系统学习目录 知识总结顺序参考C Primer Plus&#xff08;第六版&#xff09;和谭浩强老师的C程序设计&#xff08;第五版&#xff09;等&#xff0c;内容以书中为标准&#xff0c;同时参考其它各类书籍以及优质文章&#xff0c;以至减少知识点上的…

面试篇:Java基础

目录 一、HashMap 的底层结构和原理 1、JDK7 2、JDK8 3、扩容问题 二、讲一下你对动态代理的理解 1、JDK动态代理 2、CGLIB动态代理 三、Java 集合体系的划分、List、Set、Map 的区别 四、ArrayList 和 LinkedList 的区别 1、数据结构实现&#xff1a; 2、随机访问&a…