美食网站建设多少钱,网站热力图工具,北京高端 网站建设,建筑公司企业信用分全网唯一物联网MQTT协议报文结构分析以及基于C#代码的报文组装实现介绍MQTT是一种基于TCP/IP协议的应用层协议#xff0c;它规定了不同应用之间进行数据交换时的传送格式。既然是协议#xff0c;理论上可以被任何开发语言实现它#xff0c;以运行在任何平台#xff0c;这个… 全网唯一物联网MQTT协议报文结构分析以及基于C#代码的报文组装实现介绍MQTT是一种基于TCP/IP协议的应用层协议它规定了不同应用之间进行数据交换时的传送格式。既然是协议理论上可以被任何开发语言实现它以运行在任何平台这个特性就可以将所有可联网的物品通过此协议的方式进行数据通信这是其一之所以被物联网所青睐还因为它的几个主要的特性:1、使用发布/订阅消息模式提供一对多的消息发布解除耦合各终端之间无关2、对负载内容屏蔽的消息传输可以对消息订阅者所接受到的内容有所屏蔽3、具体有三种消息发布的服务质量以后细说4、小型传输开销小固定长度的头部是 2 字节协议交换最小化以降低网络流量5、使用Last Will和Testament特性通知有关各方客户端异常中断的机制应用实现为了更方便的抓包分析进行了MQTT协议的服务端与客户端的应用实现运行机制服务端通过云端一个服务器程序开启MQTT服务器Broker常见的如EMQ客户端不管是IoT管理应用程序还是IoT设备都属性于客户端程序订阅各客户端程序如果想要接收到别人发送过来的数据就需要订阅一个主题Topic发布任何客户端都可以根据一个主题向服务器发布消息服务器会根据订立记录将消息推送至订阅了对应主题的客户端数据传输格式MQTT报文大体上包含三大部分固定报头、可变报头、报文载荷整体结构如下固定报头第一个字节中高4位保存了消息的类型信息包含1-14种类型5.0版本扩充了第15个认证交换1 CONNECT – 连接服务端2 CONNACK – 确认连接请求3 PUBLISH – 发布消息4 PUBACK –发布确认5 PUBREC – 发布收到QoS 2第一步6 PUBREL – 发布释放QoS 2第二步7 PUBCOMP – 发布完成QoS 2第三步8 SUBSCRIBE - 订阅主题9 SUBACK – 订阅确认10 UNSUBSCRIBE –取消订阅11 UNSUBACK – 取消订阅确认12 PINGREQ – 心跳请求13 PINGRESP – 心跳响应14 DISCONNECT – 断开连接15 AUTH – 认证交换可变报头报文载荷报文截获利用 WireShark进行报文截获以连接请求报文为例C#代码实现此处以客户端发送连接请求为例完整报文拼接实例如下static void Main(string[] args)
{Console.WriteLine(欢迎关注朝夕教育我是Jovan);try{string ip 127.0.0.1;int port 1883;string username admin;string password 123456;string clientId C001;//Socket socketClient new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);socketClient.Connect(ip, port);Console.WriteLine( TCP 连接通道已建立);// 建立MQTT连接{// 构建MQTT报文Listbytes new List();bytes.AddRange(new byte[] { 0, 4 });// Protocol Name Lengthbytes.AddRange(Encoding.ASCII.GetBytes(MQTT));// Protocol Namebytes.Add(4);byte flag 0;flag | 128;// 用户名标记flag | 64; // 密码标记flag | 2; // Clean Session 标记bytes.Add(flag);// KeepAlivebyte[] bytesKeepAlive BitConverter.GetBytes((int)TimeSpan.FromSeconds(100).TotalSeconds);bytes.Add(bytesKeepAlive[1]);bytes.Add(bytesKeepAlive[0]);// ClientIDbyte[] clienIdBytes Encoding.ASCII.GetBytes(clientId);bytes.Add((byte)(clienIdBytes.Length / 256));bytes.Add((byte)(clienIdBytes.Length % 256));// 长度占两个字节bytes.AddRange(clienIdBytes);// UserNamebyte[] usernameBytes Encoding.ASCII.GetBytes(username);bytes.Add((byte)(usernameBytes.Length / 256));bytes.Add((byte)(usernameBytes.Length % 256));// 长度占两个字节bytes.AddRange(usernameBytes);// Passwordbyte[] passwordBytes Encoding.ASCII.GetBytes(password);bytes.Add((byte)(passwordBytes.Length / 256));bytes.Add((byte)(passwordBytes.Length % 256));// 长度占两个字节bytes.AddRange(passwordBytes);byte[] bufferLen new byte[] { (byte)bytes.Count };MemoryStream memoryStream new MemoryStream();memoryStream.WriteByte(1 4);memoryStream.Write(bufferLen, 0, (int)bufferLen.Length);memoryStream.Write(bytes.ToArray(), 0, (int)bytes.Count);byte[] array memoryStream.ToArray();memoryStream.Close();socketClient.Send(array);}}catch (Exception ex){Console.WriteLine(ex.Message);}Console.ReadLine();
}