关于TCP和MQTT之间的转换
現(xiàn)在物聯(lián)網(wǎng)流行的就是MQTT
其實(shí)MQTT就是在TCP的基礎(chǔ)上建立了一套協(xié)議
視頻教程
https://www.bilibili.com/video/av59673217
https://www.bilibili.com/video/av55614464
https://www.bilibili.com/video/av55616834
?
可以看這個(gè),本來我自己想用Wireshark監(jiān)聽一下,不過百度一搜索一大把,我就不測試了
https://blog.csdn.net/libaineu2004/article/details/78773610
?
所以說只要可以TCP連接了,然后只要知道了MQTT的協(xié)議,,,,直接就可以用TCP來當(dāng)做MQTT來使用了
不過要寫一些配合MQTT通信的協(xié)議,然后發(fā)送和接收數(shù)據(jù)都通過協(xié)議處理之后,通過TCP發(fā)送和接收,
其實(shí)有現(xiàn)成的寫好的協(xié)議
可以看這兩篇
http://sun2y.me/2017/05/12/MQTT協(xié)議在STM32上的移植/
https://blog.csdn.net/kh766200466/article/details/79694119
?
?
我也打算先移植(應(yīng)用)到stm32上,不過我不打算用網(wǎng)絡(luò)模塊W5500,雖然用的挺熟,感覺沒有新鮮感
?
我感覺應(yīng)該用ESP8266實(shí)現(xiàn)
其實(shí)思路很簡單,8266建TCP客戶端(用AT指令),因?yàn)楝F(xiàn)在沒有AT指令版的MQTT,所以用AT指令配置8266
然后連接的服務(wù)器的地址是我的云端的MQTT,當(dāng)然TCP是透傳的,然后發(fā)數(shù)據(jù)的時(shí)候都通過MQTT協(xié)議封裝部分的程序,然后
發(fā)給WIFI模塊,然后WIFI模塊再發(fā)給MQTT服務(wù)器,,,接收也一樣......然后....就沒然后了,,可以用了再說
?
?不過剛剛好像看透了一樣.......
其實(shí)呢...只要用網(wǎng)絡(luò)監(jiān)控的軟件看見了數(shù)據(jù),然后再看下面的MQTT協(xié)議.....就可以自己寫了
?
https://mcxiaoke.gitbooks.io/mqtt-cn/content/
咱試一試自己寫,我呢只是看著協(xié)議和傳回來的數(shù)據(jù),,,然后咱自己試一試寫個(gè)在TCP連接之后,發(fā)個(gè)數(shù)據(jù)(就是MQTT規(guī)定的協(xié)議)連接MQTT
?
首先第一個(gè)字節(jié)是
0x10
?
?
?
?
算啦還是直接一張圖搞定
?
用TCP連接上以后,然后用TCP發(fā)上面的指令,,,就連接上MQTT了 .....
?然后測試一下把........................................
?
?
然后就不說了,也不想說了,大家自己看協(xié)議把,,,,因?yàn)樽屪约焊杏XMQTT在我心中的地位大大的受到了..........唉,,,,感覺自己講出來的東西確實(shí)感覺竟然的如此的簡單......
只要弄透了,自己寫協(xié)議就好啦,.....我自己去寫協(xié)議去,估計(jì)寫的變量少一點(diǎn),51單片機(jī)就可以....
?
最后說一下如果是4版本的MQTT
?
?
?
然后今天寫好了單片機(jī)程序,用自己寫的MQTT封裝的協(xié)議,在8266作為TCP客戶端的基礎(chǔ)上,連接了我的云端的MQTT服務(wù)器,然后用調(diào)試助手測試了遠(yuǎn)程通信,代碼很少,力求可以直接移植到51單片機(jī)上
? ? ? ? ? ??
?
?
#define MQTTCONFIG_C_ #include "include.h"unsigned char MqttSendData[70]={0};/** * @brief 連接服務(wù)器的打包函數(shù) * @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訂閱/取消訂閱數(shù)據(jù)打包函數(shù) * @param SendData * @param topic 主題 * @param qos 消息等級(jí) * @param whether 訂閱/取消訂閱請(qǐng)求包 * @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 //消息類型和標(biāo)志 SUBSCRIBE 訂閱elseMqttSendData[index++] = 0xA2; //0xA2 取消訂閱MqttSendData[index++] = topiclen + 5; //剩余長度(不包括固定頭部)MqttSendData[index++] = 0; //消息標(biāo)識(shí)符,高位MqttSendData[index++] = 0x01; //消息標(biāo)識(shí)符,低位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級(jí)別index++;}return index; }/** * @brief MQTT發(fā)布數(shù)據(jù)打包函數(shù) * @param mqtt_message * @param topic 主題 * @param qos 消息等級(jí) * @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;//數(shù)據(jù)長度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];//拷貝數(shù)據(jù) }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?
轉(zhuǎn)載于:https://www.cnblogs.com/yangfengwu/p/9124299.html
總結(jié)
以上是生活随笔為你收集整理的关于TCP和MQTT之间的转换的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vscode 插件设置
- 下一篇: 2017-2018-2 20165301