关于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[70]={0};/** * @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 = 0;int Index = 2;int i = 0;DataLen = 12 + 2+2+ClientIDLen+UsernameLen+PasswordLen;MqttSendData[0] = 0x10; //MQTT Message Type CONNECTMqttSendData[1] = DataLen; //剩余长度(不包括固定头部)MqttSendData[Index++] = 0; // Protocol Name Length MSB MqttSendData[Index++] = 4; // 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++] = 4; // MQTT Protocol version = 4 MqttSendData[Index++] = 0xc2; // conn flags MqttSendData[Index++] = 0; // Keep-alive Time Length MSB MqttSendData[Index++] = 60; // Keep-alive Time Length LSB 60S心跳包 MqttSendData[Index++] = (0xff00&ClientIDLen)>>8;// Client ID length MSB MqttSendData[Index++] = 0xff&ClientIDLen; // Client ID length LSB for(i = 0; i < ClientIDLen; i++){MqttSendData[Index + i] = ClientID[i]; }Index = Index + ClientIDLen;if(UsernameLen > 0){ MqttSendData[Index++] = (0xff00&UsernameLen)>>8;//username length MSB MqttSendData[Index++] = 0xff&UsernameLen; //username length LSB for(i = 0; i < UsernameLen ; i++){MqttSendData[Index + i] = Username[i]; }Index = Index + UsernameLen;}if(PasswordLen > 0){ MqttSendData[Index++] = (0xff00&PasswordLen)>>8;//password length MSB MqttSendData[Index++] = 0xff&PasswordLen; //password length LSB for(i = 0; 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=0,index = 0;if(whether)MqttSendData[index++] = 0x82; //0x82 //消息类型和标志 SUBSCRIBE 订阅elseMqttSendData[index++] = 0xA2; //0xA2 取消订阅MqttSendData[index++] = topiclen + 5; //剩余长度(不包括固定头部)MqttSendData[index++] = 0; //消息标识符,高位MqttSendData[index++] = 0x01; //消息标识符,低位MqttSendData[index++] = (0xff00&topiclen)>>8; //主题长度(高位在前,低位在后)MqttSendData[index++] = 0xff&topiclen; //主题长度 for (i = 0;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=0; static u16 id=0;MqttSendData[index++] = 0x30; // MQTT Message Type PUBLISH if(qos)MqttSendData[index++] = 2 + topic_length + 2 + message_length;//数据长度elseMqttSendData[index++] = 2 + topic_length + message_length; // Remaining length MqttSendData[index++] = (0xff00&topic_length)>>8;//主题长度MqttSendData[index++] = 0xff&topic_length;for(i = 0; i < topic_length; i++){MqttSendData[index + i] = topic[i];//拷贝主题 }index += topic_length;if(qos){MqttSendData[index++] = (0xff00&id)>>8;MqttSendData[index++] = 0xff&id;id++;}for(i = 0; 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_ #endifMQTTCONFIG_C_ unsigned char MqttSendData[200];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
转载于:https://www.cnblogs.com/yangfengwu/p/9124299.html
关于TCP和MQTT之间的转换相关推荐
- java byte转16进制_Java 十六进制(Hex)与byte数组之间的转换
一.十六进制(Hex)与字节(byte)的概念 十六进制(Hex):计算机中数据的一种表示方法,它由0-9,A-F组成,字母不区分大小写.与10进制的对应关系是:0-9对应0-9:A-F对应10-15 ...
- ip(点分十进制 == 二进制整数)之间的转换
linux的套接字部分比较容易混乱,在这里稍微总结一下. 地址转换函数在地址的文本表达式和它们存放在套接字地址结构中的二进制值进行转换. 地址转换函数有四个:其中inet_addr 和 inet_nt ...
- 位(bit)与字节(byte)16进制值表现形式之间的转换
小白近很长时间未更新,是因为换工作了,目前行业是涉及到硬件的的工作. 今日因工作需要,学习到了位(bit)与字节(byte)16进制值表现形式之间的转换,故此记录一下. 下面的内容为位(bit)与字节 ...
- 时间不同单位之间的转换
在观察仿真波形的时候,经常会出现微妙,毫秒,皮秒之间的转换,出现过错误,每次记不清楚的时候还要重新查资料,现总结如下. 秒(second)是国际单位制中时间的基本单位,符号是s.有时也会借用英文缩写标 ...
- java类型转换面试题_JavaSE:数据类型之间的转换(附常见面试题)
数据类型之间的转换 分为以下几种情况: 1)低级到高级的自动类型转换: 2)高级到低级的强制类型转换(会导致溢出或丢失精度): 3)基本类型向类类型转换: 4)基本类型向字符串的转换: 5)类类型向字 ...
- java 嵌套对象转xml_Gson对Java嵌套对象和JSON字符串之间的转换 | 学步园
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,具有良好的跨平台特性.近几年来已经和XML一样成为C/S架构中广泛采用的数据格式.有关JSON的更多知识, ...
- ROS与PCL中点云数据之间的转换
此为文章初稿还没有完善,应该还有一些问题,等待后面有时间再继续更新,原创文章,未经允许,请勿转载!!! 首先介绍在PCL库中经常使用的两种点云之间的转换,这里将根据工程中的经验,从代码层面举例分析如何 ...
- 日期与unix时间戳之间的转换C++实现
之前在https://blog.csdn.net/fengbingchun/article/details/107023645 中介绍过gmtime和localtime的区别,这里介绍下日期与Unix ...
- java怎么改变数据类型_java数据类型之间的转换,是怎么回事啊? - 收获啦
1.数据类型的分类 2.比较数据类型之间的字节大小 1字节=8位 . 3.转换中的知识点 *java中整数类型默认的int类型:小数类型默认的double: *String的字符串转化为char类型时 ...
最新文章
- 应用Spark解决Kaggle数据科学问题
- 系统搜索功能不能使用,弹出“无法找到运行搜索助理需要的一个文件”
- asp.net 页面从初始化到卸载事件顺序(及对页面控件调用)完整列表【转】
- 如何高效学Python?好用的爬虫工具又有哪些?
- 我们讨论的是《战争之城》的一个简单版本。如果地图上只有空旷的空间,河流,钢墙和砖墙。你的任务是尽快得到奖金,假设没有敌人会打扰你(见下图) 你的坦克不能穿过河流和墙壁,但它可以通过射击摧毁砖墙。当你击
- LLVM每日谈之三 如何创建一个LLVM工程
- Asp.Net Core Mvc上Json序列化首字母大小写的问题
- 微信公众号涨粉攻略大全及实战
- [转][职业导航]作为初涉销售的年轻人,你是否具备核心竞争力?
- vs2015开发在网页中调用的ocx控件详解(二)
- win10如何修改mac地址(亲测通过)
- ln火线零线_ln线哪个是火线零线
- Intellij IDEA--将Java项目打包为jar包--方法/实例
- 请不要再记笔记了,四个词把人分为四类,最糟糕的一类人,颠覆了我们的认知。
- 中国平安增持华夏幸福5.69%股权
- java 企业邮箱_java 企业邮箱群发邮件
- QuickSDK-手游出海服务器接入技巧
- daocloud mysql_DaoCloud Services 开放 API
- 增加samba用户提示Failed to add entry for user
- Verilog 编程实验(6)-4位移位寄存器的设计与实现