查看: 12|回覆: 0

MQTT协议

[複製鏈接]

2

主題

0

回帖

0

積分

热心网友

金币
0
閲讀權限
220
精華
0
威望
0
贡献
0
在線時間
0 小時
註冊時間
2009-3-18
發表於 2025-9-28 10:16:00 | 顯示全部樓層 |閲讀模式
//请求连接
void mqtt_connect(char *clientid,char *username,char *passwd)
{
	uint32_t clientid_len = strlen(clientid);
	uint32_t username_len = strlen(username);
	uint32_t passwd_len = strlen(passwd);
	//用于存储剩余长度 = 可变包头+有效载荷(客户端id+2+用户名+2+密码+2);
	uint32_t remain_len = 10 + (clientid_len+2)+ (username_len+2)+ (passwd_len+2);
	//1 对发送缓冲区进行初始化
	memset((char *)sendbuf,0,512);
	sendcnt = 0;
	//2 固定包头
	sendbuf[sendcnt++] = 0x10;//connect
	//3 对剩余长度进行编码
	do
	{
		uint8_t encodeByte = remain_len %128;
		remain_len = remain_len /128;
		if(remain_len >0)
		{
			encodeByte = encodeByte |128;
		}
		sendbuf[sendcnt++] = encodeByte;
	}
	while(remain_len >0);
	//4 可变包头
	sendbuf[sendcnt++] = 0;
	sendbuf[sendcnt++] = 4;
	sendbuf[sendcnt++] = 'M';//协议名称
	sendbuf[sendcnt++] = 'Q';
	sendbuf[sendcnt++] = 'T';
	sendbuf[sendcnt++] = 'T';
	sendbuf[sendcnt++] = 4;//协议版本
	sendbuf[sendcnt++] = 0xc2 ;//连接标志
	sendbuf[sendcnt++] = 0 ;//保持连接
	sendbuf[sendcnt++] = 120 ;//2分钟
	//5 有效载荷 客户端id 用户名 密码
	sendbuf[sendcnt++] = BYTE1(clientid_len); //msb
	sendbuf[sendcnt++] = BYTE0(clientid_len);	//lsb
	
	memcpy(&sendbuf[sendcnt] ,clientid,clientid_len);
	sendcnt +=clientid_len;
	
	sendbuf[sendcnt++] = BYTE1(username_len); //msb
	sendbuf[sendcnt++] = BYTE0(username_len);	//lsb
	
	memcpy(&sendbuf[sendcnt] ,username,username_len);
	sendcnt +=username_len;
	
	sendbuf[sendcnt++] = BYTE1(passwd_len); //msb
	sendbuf[sendcnt++] = BYTE0(passwd_len);	//lsb
	
	memcpy(&sendbuf[sendcnt] ,passwd,passwd_len);
	sendcnt +=passwd_len;
	//6 把connect报文发送出去
	Serial_Sendstring(sendbuf,sendcnt);
}

//发布消息
void mqtt_publish(char *topic,uint8_t Qos,char *databuf)
{
	uint32_t remain_len;
	uint32_t topic_len = strlen(topic);
	uint32_t databuf_len = strlen(databuf);//有效载荷
	//用于存储剩余长度 = 可变包头+有效载荷(客户端id+2+用户名+2+密码+2);
	if(Qos == 0)
	{
		remain_len = (topic_len+2)+(databuf_len);
	}
	else
	{
		remain_len = (topic_len+2)+(databuf_len) + 2;
	}
	
	//1 对发送缓冲区进行初始化
	memset((char *)sendbuf,0,512);
	sendcnt = 0;
	//2 固定包头
	sendbuf[sendcnt++] = 0x30;//connect
	//3 对剩余长度进行编码
	do
	{
		uint8_t encodeByte = remain_len %128;
		remain_len = remain_len /128;
		if(remain_len >0)
		{
			encodeByte = encodeByte |128;
		}
		sendbuf[sendcnt++] = encodeByte;
	}
	while(remain_len >0);
	//可变包头
	sendbuf[sendcnt++] = BYTE1(topic_len); //msb
	sendbuf[sendcnt++] = BYTE0(topic_len);	//lsb
	
	memcpy(&sendbuf[sendcnt] ,topic,topic_len);
	sendcnt +=topic_len;
	//有效载荷
//	sendbuf[sendcnt++] = BYTE1(databuf_len); //msb
//	sendbuf[sendcnt++] = BYTE0(databuf_len);	//lsb
	
	memcpy(&sendbuf[sendcnt] ,databuf,databuf_len);
	sendcnt +=databuf_len;
	
	//6 把connect报文发送出去
	Serial_Sendstring(sendbuf,sendcnt);
}
//订阅消息
void mqtt_subscribe(const char *Filter, uint16_t msg_id, uint8_t qos)
{
 char data[256] = {0};
    int cnt = 0;
    uint32_t remain;

    // 固定包头
    data[cnt++] = 0x82; // 订阅消息类型

    // 计算剩余字节长度
    uint32_t Filter_len = strlen(Filter);
    remain = 2 + Filter_len + 2 + 1; // 消息 ID (2 字节) + 主题长度 (2 字节) + 主题 (Filter_len 字节) + QoS (1 字节)

    // 编码剩余字节
    do
    {
        uint8_t encodeByte = remain % 128;
        remain = remain / 128;
        if (remain > 0)
        {
            encodeByte |= 128;
        }
        data[cnt++] = encodeByte;
    }
    while (remain > 0);

    // 可变包头
    data[cnt++] = BYTE1(msg_id); // 消息 ID 高字节
    data[cnt++] = BYTE0(msg_id); // 消息 ID 低字节

    // 有效载荷
    data[cnt++] = BYTE1(Filter_len); // 主题长度高字节
    data[cnt++] = BYTE0(Filter_len); // 主题长度低字节
    memcpy(&data[cnt], Filter, Filter_len); // 主题
    cnt += Filter_len;
    data[cnt++] = qos; // QoS 级别

    // 发送构建的 MQTT 消息
    Serial_Sendstring(data, cnt);
}

//保持心跳请求
void mqtt_keepalive()
{
	uint8_t buf[2] = {0xc0,0x00};
	
}


来源:https://www.cnblogs.com/lradian/p/19116215
回覆

使用道具 舉報

您需要登錄後才可以回帖 登錄 | 立即注册

本版積分規則

相关侵权、举报、投诉及建议等,请发 E-mail:qiongdian@foxmail.com

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部