現在物聯網流行的就是MQTT
其實MQTT就是在TCP的基礎上建立了一套協議
可以看這個,本來我自己想用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 CONNECT
MqttSendData[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 訂閱
else
MqttSendData[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;//數據長度
else
MqttSendData[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_ #endif MQTTCONFIG_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

