• 关于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 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
  • 相关阅读:
    更新的OPENCV资料
    单通道图像的直方图(C/C++源代码)
    Java2下Applet数字签名具体实现方法
    采用HVS的图像相似度准则计算WPSNR
    彩色图像分割的FLOOD FILL方法(源代码)
    数字图像的直方图均衡化(C/C++源代码)
    彩色图像分割的FLOOD FILL方法(源代码)
    14、C++ Primer 4th 笔记,迭代器
    16、C++ Primer 4th 笔记,static(静态)类成员
    12、C++ Primer 4th 笔记,关联容器(2)
  • 原文地址:https://www.cnblogs.com/yangfengwu/p/9124299.html
Copyright © 2020-2023  润新知