关于TCP和MQTT之间的转换
现在物联网流行的就是MQTT
其实MQTT就是在TCP的基础上建立了一套协议
视频教程
https://www.bilibili.com/video/av59673217
https://www.bilibili.com/video/av55614464
https://www.bilibili.com/video/av55616834
可以看这个,本来我自己想用Wireshark监听一下,不过百度一搜索一大把,我就不测试了
https://blog.csdn.net/libaineu2004/article/details/78773610
所以说只要可以TCP连接了,然后只要知道了MQTT的协议,,,,直接就可以用TCP来当做MQTT来使用了
不过要写一些配合MQTT通信的协议,然后发送和接收数据都通过协议处理之后,通过TCP发送和接收,
其实有现成的写好的协议
可以看这两篇
http://sun2y.me/2017/05/12/MQTT协议在STM32上的移植/
https://blog.csdn.net/kh766200466/article/details/79694119
我也打算先移植(应用)到stm32上,不过我不打算用网络模块W5500,虽然用的挺熟,感觉没有新鲜感
我感觉应该用ESP8266实现
其实思路很简单,8266建TCP客户端(用AT指令),因为现在没有AT指令版的MQTT,所以用AT指令配置8266
然后连接的服务器的地址是我的云端的MQTT,当然TCP是透传的,然后发数据的时候都通过MQTT协议封装部分的程序,然后
发给WIFI模块,然后WIFI模块再发给MQTT服务器,,,接收也一样......然后....就没然后了,,可以用了再说
不过刚刚好像看透了一样.......
其实呢...只要用网络监控的软件看见了数据,然后再看下面的MQTT协议.....就可以自己写了
https://mcxiaoke.gitbooks.io/mqtt-cn/content/
咱试一试自己写,我呢只是看着协议和传回来的数据,,,然后咱自己试一试写个在TCP连接之后,发个数据(就是MQTT规定的协议)连接MQTT
首先第一个字节是
0x10
算啦还是直接一张图搞定
用TCP连接上以后,然后用TCP发上面的指令,,,就连接上MQTT了 .....
然后测试一下把........................................
然后就不说了,也不想说了,大家自己看协议把,,,,因为让自己感觉MQTT在我心中的地位大大的受到了..........唉,,,,感觉自己讲出来的东西确实感觉竟然的如此的简单......
只要弄透了,自己写协议就好啦,.....我自己去写协议去,估计写的变量少一点,51单片机就可以....
最后说一下如果是4版本的MQTT
然后今天写好了单片机程序,用自己写的MQTT封装的协议,在8266作为TCP客户端的基础上,连接了我的云端的MQTT服务器,然后用调试助手测试了远程通信,代码很少,力求可以直接移植到51单片机上
#define MQTTCONFIG_C_
#include "include.h" unsigned char MqttSendData[7]={}; /**
* @brief 连接服务器的打包函数
* @param
* @retval
* @example
**/
int ConnectMqtt(char *ClientID,char *Username,char *Password)
{
int ClientIDLen = strlen(ClientID);
int UsernameLen = strlen(Username);
int PasswordLen = strlen(Password);
int DataLen = ;
int Index = ;
int i = ;
DataLen = + ++ClientIDLen+UsernameLen+PasswordLen;
MqttSendData[] = 0x10; //MQTT Message Type CONNECT
MqttSendData[] = DataLen; //剩余长度(不包括固定头部)
MqttSendData[Index++] = ; // Protocol Name Length MSB
MqttSendData[Index++] = ; // Protocol Name Length LSB
MqttSendData[Index++] = 'M'; // ASCII Code for M
MqttSendData[Index++] = 'Q'; // ASCII Code for Q
MqttSendData[Index++] = 'T'; // ASCII Code for T
MqttSendData[Index++] = 'T'; // ASCII Code for T
MqttSendData[Index++] = ; // MQTT Protocol version = 4
MqttSendData[Index++] = 0xc2; // conn flags
MqttSendData[Index++] = ; // Keep-alive Time Length MSB
MqttSendData[Index++] = ; // Keep-alive Time Length LSB 60S心跳包
MqttSendData[Index++] = (0xff00&ClientIDLen)>>;// Client ID length MSB
MqttSendData[Index++] = 0xff&ClientIDLen; // Client ID length LSB for(i = ; i < ClientIDLen; i++)
{
MqttSendData[Index + i] = ClientID[i];
}
Index = Index + ClientIDLen; if(UsernameLen > )
{
MqttSendData[Index++] = (0xff00&UsernameLen)>>;//username length MSB
MqttSendData[Index++] = 0xff&UsernameLen; //username length LSB
for(i = ; i < UsernameLen ; i++)
{
MqttSendData[Index + i] = Username[i];
}
Index = Index + UsernameLen;
} if(PasswordLen > )
{
MqttSendData[Index++] = (0xff00&PasswordLen)>>;//password length MSB
MqttSendData[Index++] = 0xff&PasswordLen; //password length LSB
for(i = ; i < PasswordLen ; i++)
{
MqttSendData[Index + i] = Password[i];
}
Index = Index + PasswordLen;
}
return Index;
} /**
* @brief MQTT订阅/取消订阅数据打包函数
* @param SendData
* @param topic 主题
* @param qos 消息等级
* @param whether 订阅/取消订阅请求包
* @retval
* @example
**/
int MqttSubscribeTopic(char *topic,u8 qos,u8 whether)
{
int topiclen = strlen(topic);
int i=,index = ; if(whether)
MqttSendData[index++] = 0x82; //0x82 //消息类型和标志 SUBSCRIBE 订阅
else
MqttSendData[index++] = 0xA2; //0xA2 取消订阅
MqttSendData[index++] = topiclen + ; //剩余长度(不包括固定头部)
MqttSendData[index++] = ; //消息标识符,高位
MqttSendData[index++] = 0x01; //消息标识符,低位
MqttSendData[index++] = (0xff00&topiclen)>>; //主题长度(高位在前,低位在后)
MqttSendData[index++] = 0xff&topiclen; //主题长度 for (i = ;i < topiclen; i++)
{
MqttSendData[index + i] = topic[i];
}
index = index + topiclen; if(whether)
{
MqttSendData[index] = qos;//QoS级别
index++;
}
return index;
} /**
* @brief MQTT发布数据打包函数
* @param mqtt_message
* @param topic 主题
* @param qos 消息等级
* @retval
* @example
**/
int MqttPublishData(char * topic, char * message, u8 qos)
{
int topic_length = strlen(topic);
int message_length = strlen(message);
int i,index=;
static u16 id=; MqttSendData[index++] = 0x30; // MQTT Message Type PUBLISH if(qos)
MqttSendData[index++] = + topic_length + + message_length;//数据长度
else
MqttSendData[index++] = + topic_length + message_length; // Remaining length MqttSendData[index++] = (0xff00&topic_length)>>;//主题长度
MqttSendData[index++] = 0xff&topic_length; for(i = ; i < topic_length; i++)
{
MqttSendData[index + i] = topic[i];//拷贝主题
}
index += topic_length; if(qos)
{
MqttSendData[index++] = (0xff00&id)>>;
MqttSendData[index++] = 0xff&id;
id++;
} for(i = ; i < message_length; i++)
{
MqttSendData[index + i] = message[i];//拷贝数据
}
index += message_length; return index;
}
#ifndef MQTTCONFIG_H_
#define MQTTCONFIG_H_
#include <stm32f10x.h>
#ifndef MQTTCONFIG_C_//如果没有定义 _TIME_C_
#define MQTTCONFIG_C_ extern
#else
#define MQTTCONFIG_C_
#endif MQTTCONFIG_C_ unsigned char MqttSendData[]; int ConnectMqtt(char *ClientID,char *Username,char *Password);
int MqttSubscribeTopic(char *topic,u8 qos,u8 whether);
int MqttPublishData(char * topic, char * message, u8 qos); #endif
关于TCP和MQTT之间的转换的更多相关文章
- 关于TCP和MQTT之间的转换(转载)
现在物联网流行的就是MQTT 其实MQTT就是在TCP的基础上建立了一套协议 可以看这个,本来我自己想用Wireshark监听一下,不过百度一搜索一大把,我就不测试了 https://blog.csd ...
- ip(点分十进制 <==> 二进制整数)之间的转换
linux的套接字部分比较容易混乱,在这里稍微总结一下. 地址转换函数在地址的文本表达式和它们存放在套接字地址结构中的二进制值进行转换. 地址转换函数有四个:其中inet_addr 和 inet_nt ...
- JSON字符串和JS对象之间的转换
JSON字符串和JS对象之间的转换 1 json字符串转换为js对象 1.1 标准json格式字符串转换为Js对象 JSON字符串 str JSON.parse(str) eval(str) eva ...
- C# Stream 和 byte[] 之间的转换
一. 二进制转换成图片 MemoryStream ms = new MemoryStream(bytes); ms.Position = ; Image img = Image.FromStream( ...
- Java基础——基本类型和包装类、基本类型和字符串之间的转换
基本类型和包装类之间的转换 基本类型和包装类之间经常需要互相转换,以 Integer 为例(其他几个包装类的操作雷同哦): 在 JDK1.5 引入自动装箱和拆箱的机制后,包装类和基本类型之间的转换就更 ...
- String类型和基本数据类型之间的转换
Java 中基本类型和字符串之间的转换 在程序开发中,我们经常需要在基本数据类型和字符串之间进行转换. 其中,基本类型转换为字符串有三种方法: 1. 使用包装类的 toString() 方法 2. 使 ...
- Json与javaBean之间的转换工具类
/** * Json与javaBean之间的转换工具类 * * {@code 现使用json-lib组件实现 * 需要 * json-lib-2.4-jdk15.jar * ...
- Stream 和 byte[] 之间的转换
Stream 和 byte[] 之间的转换 一. 二进制转换成图片 ? 1 2 3 4 5 MemoryStream ms = new MemoryStream(bytes); ms.Position ...
- 百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换(JS版代码)
/** * Created by Wandergis on 2015/7/8. * 提供了百度坐标(BD09).国测局坐标(火星坐标,GCJ02).和WGS84坐标系之间的转换 */ //定义一些常量 ...
随机推荐
- Oracle总结二
1 where子句 Where子句的作用:用where子句来指定查询条件 1.1 用法示例 select * from emp where deptno=10; select * from emp w ...
- CSS的引入方式及CSS选择器
一 CSS介绍 现在的互联网前端分三层: a.HTML:超文本标记语言.从语义的角度描述页面结构. b.CSS:层叠样式表.从审美的角度负责页面样式. c.JS:JavaScript .从交互的角度描 ...
- npm install权限问题,报错:permission denied。
1.部署gulp项目时,nodeJs和gulp都已经正确安装,在项目内部执行npm install命令时,有些gulp的插件一直下载不成功,报错几种以下错误: “gulp-imagemin: Coul ...
- 使用 NGINX 流控和 fail2ban 防止 CC 攻击
背景知识 CC 攻击 攻击者通过创建大量请求导致服务器资源耗尽,主要针对特定服务接口,属于实现 DoS 攻击的一种方式(DoS 攻击更多是针对网络端口,而不是具体服务接口). NGINX 流控 lim ...
- (网页)readonly和disabled的区别(转)
转自脚本之家: 标签的readonly和disabled属性的区别: 在表单元素中,readonly和disable有类似之处,因为它们都可以将一些表单元素设置为"不可用"状态,当 ...
- MongoDB的基本操作:服务端启动,客户端连接,CRUD操作
本文内容: MongoDB的介绍 MongoDB服务端的启动 MongoDB客户端连接 SQL与MongoDB相关概念解释 什么是BSON 数据库操作 集合操作 文档操作 测试环境:win10 软件版 ...
- Jenkins的配置从节点中默认没有Launch agent via Java Web Start,该如何配置使用
Jenkins的配置从节点中默认没有Launch agent via Java Web Start,如下图所示,而这种启动方式在Windows上是最方便的. 如何设置才能让出来呢? 1:打开" ...
- 【PAT】B1043 输出PATest(20 分)
/* */ #include<stdio.h> #include<algorithm> #include<string.h> #include<ctype.h ...
- ccf--20150903--模板生成系统
本题思路:首先,使用一个map来存储所有需要替换的关键词,然后,再逐行的替换掉其中的关键词,记住,find每次的其实位置不一样,否则会出现递归生成没有出现关键词就清空掉.最后输出. 题目和代码如下: ...
- 记录线上一次线程hang住问题
线上发现执行某特定任务在某个特定时间点后不再work.该任务由线程池中线程执行定时周期性调度,根据日志查看无任何异常.从代码研判应该无关定时任务框架,因为对提交的定时任务做了wrap,会将异常都cat ...