STM32F407实现LwIP的MQTT客户端并连接到服务器

本文介绍如何在STM32上使用LwIP实现MQTT客户端,包括连接服务器、订阅和发布消息的过程,并提供了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

近期在做STM32之MQTT客户端连接到服务器。野火家的教程是移植别人家的MQTT客户端代码,实际LwIP源码中就包含这个,但是这个在网上很少能找到,所以我就先抛砖引玉了,有问题可以联系我哦。

MQTT介绍这里就不在说了,主要说实现方法。

这个前提是你的准备一个LwIP协议栈TCP可以正确运行起来的工程。以下说明中LwIP版本均为2.1.2,其他版本没有查看和测试,环境为keil5.34 AC6 主控为STM32F407VE。

这里先贴一个连接效果图
服务端中看到连接的客户端

这里再贴一个订阅的效果图
客户端的订阅图
这里再贴一个发布的效果图
发布的效果图
观察源码会发现,LwIP源码目录里是有关于MQTT客户端相关的API,但是几乎没有相关例程。源码位置如下图所示LwIP中MQTT的源码位置
相关头文件的位置如下图所示
LwiIP中MQTT的相关头文件位置
首先要在你的工程里包含这个源文件,如下图所示
工程中包含源文件
然后添加头文件路径,正常情况是不需要关注的(仅供参考),如下图所示
添加LwIP的头文件路径
对应的是源文件的头文件路径是这个(这里只是参考)
源文件头文件包含的实际文件夹
接下来就是实际程序编写了

#include "lwip/apps/mqtt.h"
#include "string.h"
#include "SystemLed.h"/*这个是私有的,和本次样例无关*/

void Cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status);
void cb(void *arg, err_t err);
void mipcb(void *arg, const char *topic, u32_t tot_len);
void midcb(void *arg, const u8_t *data, u16_t len, u8_t flags);

char ClientId[] = "LwIPMqttId-1";
char ClientUser[] = "LwIPMqttUser-1";
char ClientPass[] = "LwIPMqttPass-1";
char topic[] = "LwIP-TopicTest";//发布主题
char payload[] = "This is a test Info!";//发布主题的消息
char SubscribeTopic[] = "Test1";//需要订阅的主题

void MqttTestTask(void *pvParameter)
{
	while(1)
	{
		//创建一个MQTT客户端
		mqtt_client_t* MqttClient = mqtt_client_new();
		//准备MQTT服务器地址
		ip4_addr_t MqttServer;
		IP4_ADDR(&MqttServer,192,168,1,214);
		//新建一个客户端连接到服务器需要的信息块,以及填充相应的信息
		//结构体参数分别是 客户端ID 用户名 用户密码 心跳时间 遗愿主题 遗愿消息 遗愿消息等级 有无遗愿
		struct mqtt_connect_client_info_t Ci = {ClientId,ClientUser,ClientPass,10,NULL,NULL,0,0};
		//连接到服务器方法 参数分别是:客户端 服务器地址 服务器端口 连接状态变化回调 回调的参数 客户端信息
		mqtt_client_connect(MqttClient,&MqttServer,1883,Cb,NULL,&Ci);
		//这里只为测试,因为是RTOS需要调度,要等协议栈连接 上边的连接服务器方法不会阻塞 所以添加延时
		vTaskDelay(1000);
		//注册订阅信息后 收到数据的回调 参数分别是:客户端 订阅主题的回调 数据回调 回调的参数
		mqtt_set_inpub_callback(MqttClient,mipcb,midcb,NULL);
		//订阅主体 参数分别是:客户端 订阅的主题 主题的消息等级 订阅结果回调 回调参数
		mqtt_subscribe(MqttClient,SubscribeTopic,0,cb,"subscribe");
		//查询是否连接到服务器 参数:客户端
		while(mqtt_client_is_connected(MqttClient))
		{
			vTaskDelay(1000);
			//发布消息主体 参数:客户端 发布的主题 主题的消息 消息的长度 消息等级 服务器是否保留 发布结果回调 回调参数
			mqtt_publish(MqttClient,topic,payload,strlen(payload),0,0,cb,"publish");
		}
		//断开客户端到服务器的连接 参数客户端
		mqtt_disconnect(MqttClient);
		//释放创建的客户端所占内存
		mqtt_client_free(MqttClient);
		vTaskDelay(10);
	}
}

//客户端连接到服务状态  当状态发生变化时会进入这个回调
void Cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status)
{
	//源码中所有状态的例举
	switch((uint16_t)status)
	{
		case MQTT_CONNECT_ACCEPTED:;
		case MQTT_CONNECT_REFUSED_PROTOCOL_VERSION:;
		case MQTT_CONNECT_REFUSED_IDENTIFIER:;
		case MQTT_CONNECT_REFUSED_SERVER:;
		case MQTT_CONNECT_REFUSED_USERNAME_PASS:;
		case MQTT_CONNECT_REFUSED_NOT_AUTHORIZED_:;
		case MQTT_CONNECT_DISCONNECTED:;
		case MQTT_CONNECT_TIMEOUT:;
	}
}

 //订阅或者发布时的结果回调 arg是注册时给的参数 err是状态 通LwIP的状态
void cb(void *arg, err_t err)
{
	char* p = arg;
	if(strcmp(p,"publish") == 0)
		return;
	else if(strcmp(p,"subscribe") == 0)
		return;
}

//订阅主体后 客户端收到服务端推送的主题回调
void mipcb(void *arg, const char *topic, u32_t tot_len)
{
	Led2Flash();
	return;
}

//订阅主体后 客户端收到服务端推送的主题的消息回调
void midcb(void *arg, const u8_t *data, u16_t len, u8_t flags)
{
	return;
}

代码量也不多,也比较容易实现,但给我的感觉是和LwIP核心的风格不一样,所以一开始会绝的比较生涩,弄完了之后其实也不难。

### 如何解决 UniApp 中 Sass `@import` 规则废弃的问题 随着 Dart Sass 的发展,`@import` 规则已被标记为弃用,将在未来的版本中移除。因此,在开发过程中可能会遇到类似于 “Sass @import rules are deprecated and will be removed in Dart Sass 3.0.0.” 这样的警告信息[^1]。 #### 使用 `@use` 替代 `@import` Dart Sass 推荐使用 `@use` 来替代传统的 `@import` 方法来加载模块化样式文件。以下是具体的实现方式: ```html <style lang="scss"> @use './style/index.scss'; </style> ``` 通过上述代码片段可以引入指定路径下的 SCSS 文件[^3]。需要注意的是,`@use` 不仅会导入变量、函数和混合器,还会创建命名空间以便于管理不同模块中的同名定义。 #### 配置 Nuxt 或 VuePress (如果适用) 对于基于框架的应用程序(如 Nuxt),可以通过调整构建工具链设置减少此类错误提示。例如,在 `nuxt.config.ts` 文件里加入如下选项可能有助于缓解部分兼容性问题: ```typescript export default defineNuxtConfig({ vite: { css: { preprocessorOptions: { scss: { api: 'modern-compiler' } } } } }) ``` 此配置项告知 Vite 使用现代编译模式处理 CSS/SCSS 资源[^4]。尽管这是针对 Nuxt 提供的例子,但对于其他前端框架也有一定的借鉴意义。 #### 更新 Node.js 和重装依赖包 有时,环境因素也可能引发类似的错误消息。比如旧版 Node.js 可能无法完全支持最新版本的 npm 包或者其内部逻辑有所改变从而触发额外告警。此时建议尝试升级到 LTS 版本清理缓存后再执行一次完整的依赖安装过程: ```bash # 升级Node.js至LTS版本 nvm install --lts && nvm use --lts # 删除现有node_modules目录以及package-lock.json/yarn.lock锁文件 rm -rf ./node_modules package-lock.json yarn.lock # 安装最新的sass库单独测试效果 npm install sass # 正常恢复全部生产&开发所需组件 npm install ``` 以上操作能够有效排除因本地运行时差异所造成的异常状况[^2]。 --- ### 注意事项 当切换到新的语法结构后,请务必确认原有项目的全局变量声明形式是否仍然适配新标准;必要情况下需重构这些共享资源以适应更严格的语义约束。 ---
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值