MQTT客户端移植C语言

mqtt客户端源码地址:

https://github.com/eclipse/paho.mqtt.embedded-c

首先说明一下,下面Demo是在linux上跑的,展现了嵌入式MQTT客户端使用的一般流程,其核心就是把一些数据按MQTT协议打包好,再通过socket发送到服务器,你也可以移植到单片机上,比如stm32,前提是能够连接到服务通信,一般wifi模块例如esp8266,内置了TCP/IP协议栈,单片机可以直接通过AT指令联网,只需要把打包好的数据通过AT指令发送给WiFi模块,WiF模块就会把数据发送到服务器。

MQTT Subscribe Demo
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> 
#include <fcntl.h>
#include <pthread.h>
#include "src/MQTTPacket.h"

int sock;
pthread_t ping;
void * ping_thread(void * arg);
void TcpConnect(const char *host, int port);

int main(void)
{
	//建立TCP连接
	TcpConnect("127.0.0.1", 1883);
	
	//初始化连接参数,MQTTPacket_connectData_initializer定义在MQTTConnect.h
	unsigned char buf[256];
	int bufsize = sizeof(buf);
	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
	data.clientID.cstring = "zhou001";	//客户端ID
	data.keepAliveInterval = 30;	//存活时间,如果30秒内设备没有向服务器发送ping数据就会短线;
	data.cleansession = 1;	//清除会话
	data.username.cstring = "admin";	//用户名
	data.password.cstring = "admin";	//密码
	
	//打包和发送connect数据
	int len = MQTTSerialize_connect(buf, bufsize, &data);
	send(sock, buf, len, 0);
	printf("Connecting...\n");
	recv(sock, buf, bufsize, 0);	//等待连接
	
	//创建ping线程, 25秒ping一次
	pthread_create(&ping, NULL, ping_thread, NULL);
	
	//订阅主题
	MQTTString topicString = MQTTString_initializer;
	int msgid = 1;	//消息id
	int req_qos = 0;	//消息质量
	topicString.cstring = "topic1";	//主题名称
	len = MQTTSerialize_subscribe(buf, bufsize, 0, msgid, 1, &topicString, &req_qos);	//打包subscribe数据
	send(sock, buf, len, 0);	//发送subscribe数据
	printf("Subcribing...\n");
	
	while(1)
	{
		len = recv(sock, buf, bufsize, 0);
		if(len > 0)
		{
			if(buf[0] == 0x30)	//判断接收到的消息是否是publish
			{
				//解包publish数据
				unsigned char dup;
				int qos;
				unsigned char retained;
				unsigned short msgid;
				int payloadlen_in;
				unsigned char* payload_in;	//指向payload
				int rc;
				MQTTString receivedTopic;
				MQTTDeserialize_publish(&dup, &qos, &retained, &msgid, &receivedTopic,
						&payload_in, &payloadlen_in, buf, bufsize);
				printf("message arrived %.*s\n", payloadlen_in, payload_in);
			}
		}
	}
}

void TcpConnect(const char *host, int port)
{
	//创建套接字
	sock = socket(AF_INET, SOCK_STREAM, 0);
	//向服务器(特定IP和端口)发送请求
	struct sockaddr_in serv_addr;
	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = inet_addr(host);
	serv_addr.sin_port = htons(port);
	int res = connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
	if(res == 0)
		printf("TCP Connected\n");
}

void * ping_thread(void *arg)
{
	(void)arg;
	uint8_t buf[10];
	int bufsize = sizeof(buf);
	int len = 0;
	printf("Ping thread is running\n");
	while(1)
	{
		sleep(20);
		//打包和发送ping数据
		len = MQTTSerialize_pingreq(buf, bufsize);
		send(sock, buf, len, 0);
		printf("Ping...\n");
	}
}
MQTT Publish Demo
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h> 
#include <fcntl.h>
#include <pthread.h>
#include "src/MQTTPacket.h"

int sock;
pthread_t ping;
void * ping_thread(void * arg);
void TcpConnect(const char *host, int port);

int main(void)
{
	//建立TCP连接
	TcpConnect("127.0.0.1", 1883);
	
	//初始化连接参数,MQTTPacket_connectData_initializer定义在MQTTConnect.h
	unsigned char buf[256];
	int bufsize = sizeof(buf);
	MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
	data.clientID.cstring = "zhou002";	//客户端ID
	data.keepAliveInterval = 30;	//存活时间,如果30秒内设备没有向服务器发送ping数据就会短线;
	data.cleansession = 1;	//清除会话
	data.username.cstring = "admin";	//用户名
	data.password.cstring = "admin";	//密码
	
	//打包和发送connect数据
	int len = MQTTSerialize_connect(buf, bufsize, &data);
	send(sock, buf, len, 0);
	printf("Connecting...\n");
	recv(sock, buf, bufsize, 0);	//等待连接
	
	//创建ping线程,25秒ping一次
	pthread_create(&ping, NULL, ping_thread, NULL);
	
	MQTTString topicString = MQTTString_initializer;
	topicString.cstring = "topic1";
	unsigned char *payload = "hello";
	while(1)
	{
		sleep(2);
		len = MQTTSerialize_publish(buf, bufsize, 0, 0, 0, 0, topicString, payload, strlen(payload));
		send(sock, buf, len, 0);
		printf("message sent hello\n");
	}
	
}

void TcpConnect(const char *host, int port)
{
	//创建套接字
	sock = socket(AF_INET, SOCK_STREAM, 0);
	//向服务器(特定IP和端口)发送请求
	struct sockaddr_in serv_addr;
	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = inet_addr(host);
	serv_addr.sin_port = htons(port);
	int res = connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
	if(res == 0)
		printf("TCP Connected\n");
}

void * ping_thread(void *arg)
{
	(void)arg;
	uint8_t buf[10];
	int bufsize = sizeof(buf);
	int len = 0;
	printf("Ping thread is running\n");
	while(1)
	{
		sleep(25);
		//打包和发送ping数据
		len = MQTTSerialize_pingreq(buf, bufsize);
		send(sock, buf, len, 0);
		printf("Ping...\n");
	}
}
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值