MQTT入门(二)

在上一篇中,我们使用了Mosquitto作为MQTT的BrokerMQTT.fxmosquitto_submosquitto_pub作为客户端工具实现了简单订阅、发布功能

这篇仍然使用上述工具,加上Wireshark抓包工具帮助我们更加了解MQTT协议

注意:MQTT协议版本为3.1.1,只分析应用层协议

1 Connect

MQTT.fx的配置如下 image

然后我们按照如下顺序点击了一次ConnectDisconnect

Wireshark抓包情况如下:

下面逐个分析下Packets内容

1.1 Connect Command

这个Packet用于发起连接

可以看出Packet大致分为Flags和其他内容

Header Flags0x10)包含了如下信息:

  • Message Type:消息的类型,这里是Connect Command
  • Reserved:预留字段

Connect Flags0xc2)包含了如下信息:

  • User Name Flag:Set,0xc2第一位bit为1,表明该Connect请求中包含了User Name
  • Password Flag:Set,0xc2第二位bit为1,表明改Connect请求中包含了Password
  • Will Retain:Not set,0xc2第三位bit为0,向Broker表明不需要Retain(Retain的功能我们后面细说)
  • QoS Level:当前为0,取值可以是0、1、2,所以占用了0xc2第四位bit和第五位bit 2个bits,表明了当前的服务级别(Quality of Service这个我们后面细说)
  • Will Flag:Not set,0xc2第六位bit为0,这个是和遗嘱相关(这个我们后面细说)
  • Clean Session Flag:Set,0xc2第七位bit为1,,表明当此Client断开后,Broker会清除Session信息(感受就是之前向Broker订阅的topic失效)
  • Reserved:保留字段,占据0xc2第八位bit

除了以上Flags,还包含如下信息:

  • Protocol Name Length:协议名称的长度,这里是4
  • Protocol Name:协议的名称,这里是MQTT(和上面的协议名称的长度4对应)
  • Version:版本,这里是4,表明了v3.1.1(并没有使用v3.1.1表达)
  • Keep Alive:存活时间占用2字节,这里为60,默认也是60,在指定的时间之内没有活动,Broker会主动断开连接
  • Client ID Length:指明Client ID的字符长度占用2字节,这里为14
  • Client ID:指明Cleint ID,这里为MQTT_FX_Client,和上面的14长度对应,注意同一时刻只允许一个Client连接Broker,若为空则Broker会生产,则说明请求不想记录状态,Clean Session Flag则必须Set
  • User Name Length:指明User Name的长度
  • User Name:指明了User Name
  • Password LengthPassword同上

PS:
从上我们看出了MQTT协议比HTTP协议轻在了什么地方

  • MQTT协议字段内容按约定次序出现,同时标识长度,确定每个字段的分隔处,而HTTP协议字段使用\n分隔
  • MQTT使用了4表示了版本为v3.1.1,而HTTP会使用原始信息表示

使用MQTT传输上述信息内容如下:

./..MQTT...<..MQTT_FX_Client..jane@mens.de..jolie

而使用HTTP传输同样信息可能是下面这个样子的:

MQ Telemetry Transport Protocol, Connect Command

Header Flags: 0x10, Message Type: Connect Command
Msg Len: 47
Protocol Name Length: 4
Protocol Name: MQTT
Version: MQTT v3.1.1 (4)
Connect Flags: 0xc2, User Name Flag, Password Flag, QoS Level: At most once delivery (Fire and Forget), Clean Session Flag
    1... .... = User Name Flag: Set
    .1.. .... = Password Flag: Set
    ..0. .... = Will Retain: Not set
    ...0 0... = QoS Level: At most once delivery (Fire and Forget) (0)
    .... .0.. = Will Flag: Not set
    .... ..1. = Clean Session Flag: Set
    .... ...0 = (Reserved): Not set
Keep Alive: 60
Client ID Length: 14
Client ID: MQTT_FX_Client
User Name Length: 12
User Name: jane@mens.de
Password Length: 5
Password: jolie

1.2 Connect Ack

这个Packet用于对发起的连接进行响应

Header Flags同上

Msg Len:指明了消息的长度,包含了如下内容,这里是2个字节

  • Acknowledge Flags:第一个字节,为0x00,字节内部又如下分配
    • 0010 ....:前4个bits,Reserved保留字段
    • .... ...0Session Present Not set,表明没有使用之前Broker保存的session,没有继续之前的会话继续通讯
  • Return Code:第二个字节,为0,表示Connection Accepted连接成功,还包含其他访问值(如1表明版本不支持,5表明授权失败等)

客户端依据Connect Ack来判断是否连接成功,决定后面是否是继续连接等操作

1.3 Disconnect Req

这个Packet用于客户端主动断开连接,不需要收到Broker的响应

就2个字节,不需要Broker的Ack

2 Publish

MQTT.fx如下:

Wireshark如下:

2.1 Publish Message

这个Packet用于发布消息

Header Flags同上
Msg Len:指明了消息长度,是如下内容的总长度

  • Topic Length:指明了Topic长度
  • Topic:指明了topic为topic
  • Message:消息内容,这里为zqq test

3 Subscribe

MQTT.fx如下:

Wireshark如下:

3.1 Subscribe Request

这里说下Requested QoSMessage Identifier

  • Requested QoS:要区分Subscribe时指明的QoS和Publish时指明的QoS,如下图Publish时指明的QoS是PublisherBroker之间,Subscribe时指明的QoS是BrokerSubscriber之间
  • Message Identifier:这个用于标明Request/Response请求对,Response附带Request的ID,则能标识这是对特定Request的Response,针对每个session而言,一般从1开始自增

3.2 Subscribe Ack

  • Message Identifier:这里是1,说明是对消息ID为1的Subscribe Request的响应

3.3 Unsubscribe Request

  • Message Identifier:这里是2,新的操作Message Identifier自增为2

3.4 Unsubscribe Ack

4 Others

下篇介绍如下较难理解的特性:

  • Ping
  • Retain
  • Will
  • QoS

Tags:

Categories:

Updated: