MQTT消息格式之SUBSCRIBE消息分析

  物联网最近曝光率越来越高。虽然HTTP是网页的事实标准,不过机器之间(Machine-to-Machine,M2M)的大规模沟通需要不同的模式:之前的请求/回答模式不再合适,取而代之的是发布/订阅(Publish/Subscribe)模式。这就是轻量级、可扩展的MQTT(Message Queuing Telemetry Transport)可以施展拳脚的舞台。

MQTT协议文档https://www.gitbook.com/book/mcxiaoke/mqtt-cn/details

  采用WireShark抓包工具分析MQTT消息,参考http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718063分析协议包

首先运行工程

[java] view plain copy print?import org.eclipse.paho.client.mqttv3.MqttClient;  
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;  
import org.eclipse.paho.client.mqttv3.MqttException;  
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;  
 
 
public class SubScriberExample {  
 
   /** 
    * @param args 
    */  
   public static void main(String[] args) {  
        String[] topicFilters ={"topic1","topic2"} ;  
        String broker = "tcp://192.168.80.196:1883" ;  
        String clientId = "paho-1" ;  
        MemoryPersistence persistence = new MemoryPersistence();  
         try {  
                MqttClient sampleClient = new MqttClient(broker, clientId,persistence);  
                MqttConnectOptions connOpts = new MqttConnectOptions();  
                connOpts.setCleanSession( false );  
                System. out .println( "Connecting to broker: " + broker);  
                sampleClient.connect(connOpts);  
                System. out .println( "Connected" );  
                sampleClient.setCallback(new CustomMQTTCallBack());  
                sampleClient.subscribe(topicFilters,new int[]{1,1});  
                System. out .println( "Subscribe success for: "+topicFilters.toString());  
        } catch (MqttException me) {  
                System. out .println( "reason " + me.getReasonCode());  
                System. out .println( "msg " + me.getMessage());  
                System. out .println( "loc " + me.getLocalizedMessage());  
                System. out .println( "cause " + me.getCause());  
                System. out .println( "excep " + me);  
                me.printStackTrace();  
        }  
 
   }  
 
}  

当运行客户端之后通过抓取TCP数据包


MQTT消息格式之SUBSCRIBE消息分析_第1张图片
  1. 固定头部
    SUBSCRIBE 固定头部的消息格式见下表
MQTT消息格式之SUBSCRIBE消息分析_第2张图片
Paste_Image.png

从上图的抓包程序得到的数据可知,固定头部的16进制为:82 14
结合上面的表1,我们可知其具体含义如下:
82---1000 0010 表示连接的请求是Subscribe
14--1*16+4=20 表示后面将会跟着20个字节

2.可变头部

MQTT消息格式之SUBSCRIBE消息分析_第3张图片
Paste_Image.png

从上图的抓包程序得到的数据可知,可变头部的16进制为:00 01
结合上面的表2,我们可知其具体含义如下:
00 01 ---表示当前的Package的ID是1

3.负载部分
SUBSCRIBE 负载部分的消息格式见下表,负载部分主要指定订阅的主题(Topic)的名称以及每个订阅的主题对应的QoS级别(总共三种类型的值:0,1,2),需要注意的是,在负载部分,一次可以订阅多个主题。

MQTT消息格式之SUBSCRIBE消息分析_第4张图片
Paste_Image.png

从上图的抓包程序得到的数据可知,负载部分实际捕获的数据为:00 06 74 6f 70 69 63 31 01 00 06 74 6f 70 69 63 32 01 因为总共有两个主题:topic1 和topic2,所以我们拿第一个主题(topic1)来分析就行了,后面的Topic类似.
00 06 代表这个topic的长度是6个字节
74 6f 70 69 63 31 代表 topic1
01 代表QoS为1

从此看出MQTT数据包并不复杂,掌握了就能看懂。

你可能感兴趣的:(MQTT消息格式之SUBSCRIBE消息分析)