0.前言
在上一节中(MQTT消息格式之SUBSCRIBE(消息订阅)消息分析),客户端发送了订阅的消息,这个时候,服务器端收到订阅主题的MQTT消息之后,肯定需要给一个应答,这个应答信息就是SUBACK(消息订阅应答)。消息订阅应答相对来说比较简单。
1.准备步骤
(1) 首先打开WireShark软件,并启动监听
(2) 在Eclipse里面运行下面的代码
[java] view
plaincopy
- 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;
- import com.tibco.mqtt.test.CustomMQTTCallBack;
- public class SubScriberExample {
- /**
- * @param args
- */
- public static void main(String[] args) {
- String topicFilter ="test";
- 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(topicFilter,0);
- 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();
- }
- }
- }
(3) 运行之后,WireShark将能抓取到下面的TCP的数据包.
2.协议分析
下面进行具体的协议分析,协议的地址(http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718068)
2.1 固定头部(Fixed
Header)
SUBACK固定头部的消息格式见下表
表1 – SUBACK固定头部消息格式
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
byte 1 |
MQTT Control Packet type (9) |
Reserved |
||||||
1 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
|
byte 2 |
Remaining Length |
从上图的抓包程序得到的数据可知,固定头部的16进制为:90 04
结合上面的表1,我们可知其具体含义如下:
90---1001 0000 表示连接的请求是SUBACK
04-- 表示后面将会跟着4个字节
2.2 可变头部(Variable
Header)
SUBSCRIBE 可变头部的消息格式见下表,其表示的是消息的ID,分高位和低位。
表2 - 可变头部的消息格式
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
byte 1 |
Packet Identifier MSB |
|||||||
byte 2 |
Packet Identifier LSB |
从上图的抓包程序得到的数据可知,可变头部的16进制为:00 01
结合上面的表2,我们可知其具体含义如下:
00 01 ---表示当前的SUBACK的消息ID是1,这个和上节中的SUBSCRIBE(消息订阅)的消息ID的值必须保持一致。
2.3 负载部分(payload)
SUBACK负载部分的消息格式见下表,负载部分主要返回订阅的结果。其返回的值下面4中类型,其他的都是没有意义的。
允许返回的值
0x00 - 表示成功- 最大的QoS 0
0x01 -
表示成功- 最大的 QoS 1
0x02 -
表示成功- 最大的 QoS 2
0x80 -
表示订阅失败。
表3 - 负载部分的消息格式
Bit |
7 |
6 |
5 |
4 |
3 |
2 |
1 |
0 |
Return Code |
||||||||
byte 1 |
X |
0 |
0 |
0 |
0 |
0 |
X |
X |
从上图的抓包程序得到的数据可知,负载部分实际捕获的数据为:00 00
其表示消息订阅成功,且以后收到得到订阅的消息的QoS的值只能够为0.
恭喜你,已经知道了如何分析MQTT SUBACK的消息格式,这个协议相对来说比较简单。在下一节我们将分析和消息发布(Publication)的相关的消息格式分析,这一部分相对来说比较复杂。敬请期待和关注.