#include "mqtt.h"
//连接成功服务器回应 20 02 00 00
//客户端主动断开连接 e0 00
const quint8 parket_connetAck[] = {0x20,0x02,0x00,0x00};
const quint8 parket_disconnet[] = {0xe0,0x00};
const quint8 parket_heart[] = {0xc0,0x00};
const quint8 parket_heart_reply[] = {0xc0,0x00};
const quint8 parket_subAck[] = {0x90,0x03};
MQTT_WorkClass::~MQTT_WorkClass()
{
qDebug()<<"析构函数---TCP";
}
void MQTT_WorkClass::run()
{
qDebug()<<"执行:run";
m_exit_flag=0;
if(timer)
{
delete timer;
timer=nullptr;
}
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(EndEvenLoop()));
socket_type=0;
//连接到服务器
ConnectMqttServer(m_ip,m_port);
//开始事件循环
StartEvenLoop();
//初始化mqtt协议
MQTT_Init();
//连接mqtt协议
if(MQTT_Connect(m_MQTT_ClientID.toUtf8().data(),m_MQTT_UserName.toUtf8().data(),m_MQTT_PassWord.toUtf8().data()))
{
LogSend("MQTT服务器登录失败.\n");
}
else
{
//心跳包定时器
if(timer_heartbeat)
{
delete timer_heartbeat;
timer_heartbeat=nullptr;
}
timer_heartbeat = new QTimer(this);
connect(timer_heartbeat, SIGNAL(timeout()), this, SLOT(update_heartbeat()));
LogSend("MQTT服务器登录成功.\n");
}
}
void MQTT_WorkClass::MQTT_Init(void)
{
//缓冲区赋值
mqtt_rxbuf = _mqtt_rxbuf;
mqtt_rxlen = sizeof(_mqtt_rxbuf);
mqtt_txbuf = _mqtt_txbuf;
mqtt_txlen = sizeof(_mqtt_txbuf);
memset(mqtt_rxbuf,0,mqtt_rxlen);
memset(mqtt_txbuf,0,mqtt_txlen);
}
/*
函数功能: 登录服务器
函数返回值: 0表示成功 1表示失败
*/
quint8 MQTT_WorkClass::MQTT_Connect(char *ClientID,char *Username,char *Password)
{
quint8 i,j;
int ClientIDLen = strlen(ClientID);
int UsernameLen = strlen(Username);
int PasswordLen = strlen(Password);
int DataLen;
mqtt_txlen=0;
//可变报头+Payload 每个字段包含两个字节的长度标识
DataLen = 10 + (ClientIDLen+2) + (UsernameLen+2) + (PasswordLen+2);
//固定报头
//控制报文类型
mqtt_txbuf[mqtt_txlen++] = 0x10; //MQTT Message Type CONNECT
//剩余长度(不包括固定头部)
do
{
quint8 encodedByte = DataLen % 128;
DataLen = DataLen / 128;
// if there are more data to encode, set the top bit of this byte
if ( DataLen > 0 )
encodedByte = encodedByte | 128;
mqtt_txbuf[mqtt_txlen++] = encodedByte;
}while ( DataLen > 0 );
//可变报头
//协议名
mqtt_txbuf[mqtt_txlen++] = 0; // Protocol Name Length MSB
mqtt_txbuf[mqtt_txlen++] = 4; // Protocol Name Length LSB
mqtt_txbuf[mqtt_txlen++] = 'M'; // ASCII Code for M
mqtt_txbuf[mqtt_txlen++] = 'Q'; // ASCII Code for Q
mqtt_txbuf[mqtt_txlen++] = 'T'; // ASCII Code for T
mqtt_txbuf[mqtt_txlen++] = 'T'; // ASCII Code for T
//协议级别
mqtt_txbuf[mqtt_txlen++] = 4; // MQTT Protocol version = 4 对于 3.1.1 版协议,协议级别字段的值是 4(0x04)
//连接标志
mqtt_txbuf[mqtt_txlen++] = 0xc2; // conn flags
mqtt_txbuf[mqtt_txlen++] = 0; // Keep-alive Time Length MSB
mqtt_txbuf[mqtt_txlen++] = 100; // Keep-alive Time Length LSB 100S心跳包 保活时间
mqtt_txbuf[mqtt_txlen++] = BYTE1(ClientIDLen);// Client ID length MSB
mqtt_txbuf[mqtt_txlen++] = BYTE0(ClientIDLen);// Client ID length LSB
memcpy(&mqtt_txbuf[mqtt_txlen],ClientID,ClientIDLen);
mqtt_txlen += ClientIDLen;
if(UsernameLen > 0)
{
mqtt_txbuf[mqtt_txlen++] = BYTE1(UsernameLen); //username length MSB
mqtt_txbuf[mqtt_txlen++] = BYTE0(UsernameLen); //username length LSB
memcpy(&mqtt_txbuf[mqtt_txlen],Username,UsernameLen);
mqtt_txlen += UsernameLen;
}
if(PasswordLen > 0)
{
mqtt_txbuf[mqtt_txlen++] = BYTE1(PasswordLen); //password length MSB
mqtt_txbuf[mqtt_txlen++] = BYTE0(PasswordLen); //password length LSB
memcpy(&mqtt_txbuf[mqtt_txlen],Password,PasswordLen);
mqtt_txlen += PasswordLen;
}
//清空数据
memset(mqtt_rxbuf,0,mqtt_rxlen);
ReadData.clear();
MQTT_SendBuf(mqtt_txbuf,mqtt_txlen);
//开始事件循环
StartEvenLoop();
if(ReadData.length()==0)
{
//开始事件循环
StartEvenLoop();
}
memcpy((char *)mqtt_rxbuf,ReadData.data(),ReadData.length());
//CONNECT
if(mqtt_rxbuf[0]==parket_connetAck[0] && mqtt_rxbuf[1]==parket_connetAck[1]) //连接成功
{
return 0;//连接成功
}
return 1;
}
/*
函数功能: MQTT订阅/取消订阅数据打包函数
函数参数:
topic 主题
qos 消息等级 0:最多分发一次 1: 至少分发一次 2: 仅分发一次
whether 订阅/取消订阅请求包 (1表示订阅,0表示取消订阅)
返回值: 0表示成功 1表示失败
*/
quint8 MQTT_WorkClass::MQTT_SubscribeTopic(char *topic,quint8 qos,quint8 whether)
{
quint8 i,j;
mqtt_txlen=0;
int topiclen = strlen(topic);
int DataLen = 2 + (topiclen+2) + (whether?1:0);//可变报头的长度(2字节)加上有效载荷的长度
//固定报头
//控制报文类型
if(whether)mqtt_txbuf[mqtt_txlen++] = 0x82; //消息类型和标志订阅
else mqtt_txbuf[mqtt_txlen++] = 0xA2; //取消订阅
//剩余长度
do
{
quint8 encodedByte = DataLen % 128;
DataLen = DataLen / 128;
// if there are more data to encode, set the top bit of this byte
if ( DataLen > 0 )
encodedByte = encodedByte | 128;
mqtt_txbuf[mqtt_txlen++] = encodedByte;
}while ( DataLen > 0 );
//可变报头
mqtt_txbuf[mqtt_txlen++] = 0; //消息标识符 MSB
mqtt_txbuf[mqtt_txlen++] = 0x0A; //消息标识符 LSB
//有效载荷
mqtt_txbuf[mqtt_txlen++] = BYTE1(topiclen);//主题长度 MSB
mqtt_txbuf[mqtt_txlen++] = BYTE0(topiclen);//主题长度 LSB
memcpy(&mqtt_txbuf[mqtt_txlen],topic,topiclen);
mqtt_txlen += topiclen;
if(whether)
{
mqtt_txbuf[mqtt_txlen++] = qos;//QoS级别
}
ReadData.clear();
MQTT_SendBuf(mqtt_txbuf,mqtt_txlen);
//开始事件循环
StartEvenLoop();
if(ReadData.length()==0)
{
//开始事件循环
StartEvenLoop();
}
memcpy((char *)mqtt_rxbuf,ReadData.data(),ReadData.length());
if(mqtt_rxbuf[0]==parket_subAck[0] && mqtt_rxbuf[1]==parket_subAck[1]) //订阅成功
{
return 0;//订阅成功
}
return 1; //失败
}
//MQTT发布数据打包函数
//topic 主题
//message 消息
//qos 消息等级
quint8 MQTT_WorkClass::MQTT_PublishData(char *topic, char *message, quint8 qos)
{
int topicLength = strlen(topic);
int messageLength = strlen(message);
//qDebug()<<"消息长度:"<<messageLength;
//qDebug()<<"消息内容:"<<message;
static quint16 id=0;
int DataLen;
mqtt_txlen=0;
//有效载荷的长度这样计算:用固定报头中的剩余长度字段的值减去可变报头的长度
//QOS为0时没有标识符
//数据长度 主题名 报文标识符 有效载荷
if(qos) DataLen = (2+topicLength) + 2 + messageLength;
else DataLen = (2+topicLength) + messageLength;
//固定报头
//控制报文类型 这是发送包第1个字节
//报文的字节位: 7654 3 21 0
/*
第7、6、5、4位 表示是PUBLISH 报文 固定填0011
第3位 是DUP位,重发标志,如果是重发这个位就需要置位1,第一次发生置位0
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
当前基于MQTT协议设计了一个实时图传系统,通过这个项目来演示,两个MQTT设备如何互相订阅,进行消息流转。 在阿里云服务器上创建2个设备,分为为设备A和设备B;设备A负责采集本地摄像头画面上传,设备B负责接收设备A上传的数据然后解析显示出来。在阿里云服务器上需要配置云产品流转,让设备A的数据上传后自动发送给设备B。这样就完成了视频画面数据的流转。 对应的博客文章(必看):https://blog.csdn.net/xiaolong1126626497/article/details/129394219
资源推荐
资源详情
资源评论
收起资源包目录
51 利用MQTT协议+阿里云平台实现视频监控系统.zip (83个子文件)
tcp_mqtt_image_rx
widget.ui 7KB
widget.cpp 8KB
MQTT
mqtt.cpp 16KB
mqtt.h 4KB
logo.png 10KB
main.cpp 177B
tcp_mqtt_image_rx.pro 1KB
videoplayer_showvideowidget.cpp 2KB
videoplayer_showvideowidget.h 892B
logo.ico 135KB
widget.h 1KB
tcp_mqtt_image_tx
widget.ui 11KB
tcp_mqtt_image_tx.pro.user 24KB
widget.cpp 9KB
MQTT
mqtt.cpp 16KB
mqtt.h 4KB
tcp_mqtt_image_tx.pro 1KB
logo.png 10KB
camera.h 2KB
camera.cpp 7KB
main.cpp 177B
videoplayer_showvideowidget.cpp 2KB
videoplayer_showvideowidget.h 892B
logo.ico 135KB
widget.h 2KB
可执行文件
libGLESV2.dll 4.3MB
图像接收端.exe 258KB
bearer
qgenericbearer.dll 104KB
styles
qwindowsvistastyle.dll 196KB
Qt5Gui.dll 6.63MB
config.ini 128B
imageformats
qjpeg.dll 388KB
qsvg.dll 32KB
qtga.dll 31KB
qtiff.dll 522KB
qwebp.dll 450KB
qgif.dll 39KB
qicns.dll 49KB
qwbmp.dll 30KB
qico.dll 40KB
Qt5Core.dll 6.32MB
config_rx.ini 124B
Qt5Svg.dll 362KB
tcp_mqtt_image_rx.exe 258KB
Qt5Widgets.dll 6.05MB
audio
qtaudio_windows.dll 87KB
translations
qt_lv.qm 150KB
qt_sk.qm 132KB
qt_cs.qm 186KB
qt_de.qm 211KB
qt_ja.qm 141KB
qt_fi.qm 189KB
qt_da.qm 183KB
qt_ko.qm 141KB
qt_fr.qm 178KB
qt_pl.qm 171KB
qt_ar.qm 167KB
qt_it.qm 174KB
qt_bg.qm 175KB
qt_gd.qm 185KB
qt_es.qm 178KB
qt_en.qm 23B
qt_uk.qm 170KB
qt_zh_TW.qm 125KB
qt_ca.qm 194KB
qt_hu.qm 173KB
qt_he.qm 135KB
qt_ru.qm 196KB
iconengines
qsvgicon.dll 47KB
Qt5Multimedia.dll 1.02MB
platforms
qwindows.dll 1.89MB
libwinpthread-1.dll 46KB
libEGL.dll 29KB
opengl32sw.dll 15.25MB
Qt5Network.dll 1.8MB
libstdc++-6.dll 1.47MB
tcp_mqtt_image_tx.exe 275KB
D3Dcompiler_47.dll 3.31MB
libgcc_s_dw2-1.dll 111KB
playlistformats
qtmultimedia_m3u.dll 34KB
mediaservice
qtmedia_audioengine.dll 70KB
dsengine.dll 414KB
图像发送端.exe 275KB
共 83 条
- 1
DS小龙哥
- 粉丝: 5w+
- 资源: 910
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 机械设计物流双托盘提升机sw18可编辑全套设计资料100%好用.zip
- 基于Java的学院教学工作量统计系统源码(java毕业设计完整源码).zip
- 三菱plc搭配四轴雅马哈机械手在线检测收料案例程序 (包涵CAD电气图纸,plc程序,人机界面,机器人程序,BOM表)程序中应用到CClink通讯,232串口通讯,数据采集伺服定位控制
- LibUsbDotNet C#
- 机械设计消毒袋封口机x_t全套设计资料100%好用.zip
- 证件照处理的代码演示以及说明
- 基于java的招聘求职系统源码(java毕业设计完整源码).zip
- 基于Java的校园二手商品交易系统设计与实现源码(java毕业设计完整源码).zip
- 基于JAVA的校园二手物品交易系统的设计与实现源码(java毕业设计完整源码+LW).zip
- 学生考试表现影响因素数据集.zip
- 基于Java的校园消费点评系统源码(java毕业设计完整源码).zip
- 图像加解密的代码展示以及说明
- 基于Java的校园自助洗衣服务管理系统的设计与实现源码(java毕业设计完整源码).zip
- 基于Python的图像加解密技术实现
- 线性自抗扰(LADRC)的stm32f1程序,实现用编码器反馈控制直流电机调速,控制器采用加了TD的LADRC,控制效果良好,.h和.c分开,代码清晰有注释 有调试说明
- 【Endnote 文献输出样式Style Chinese std GBT7714 下载和使用】
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
- 4
- 5
前往页