工业互联-MQTT数据交换协议

MQTT协议是基于TCP协议的应用层协议

1             Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
2             socket.Connect("127.0.0.1", 9090); // 连接到服务器

连接请求报文:

1、固定报头

(1)消息类型的取值为0—15,比如分别是0000,0001,0010,0011,0100,0101,0110,0111,1000,1001,1010,1011,1100,1101,1110,1111

(2)标志位

(3)消息长度

(4)长度扩展、最大长度

字节数 最小值 最大值
1 0(0x00)   127(0x7F)
2  128(0x80,0x01)  16383(0xFF,0X7F)
3 16384(0x80,0x80,0x01)  2097151(0xFF,0xFF,0X7F)
4 2097152 (0x80,0x80,0x80,0x01) 168435455(0xFF,0xFF,0xFF,0X7F)

1
// 第1个字节 2 // 消息类型取值 3 // 取值为1,左移4位,0000 0001左移4位后0001 0000(0x10) 4 byte byte1 = 1 << 4; 5 bytes.Add(byte1); 6 // 第2个字节 7 // 暂时无法确定,1个字节最多可以表示长度为255 8 // 特殊情况,超出255字节 9 // 最高位 标记位如果是1,表示后面一个字节也是长度值(1000 0000 1000 0000 1000 0000),最大长度值可以是256M 10 // 如果是123个字节 -> 7B -> 0111 1011 11 // 如果是200个字节 -> 1000 0001 0100 1000 12 // 如果是300个字节 -> 1000 0001 0010 1100(0x01 0x2C) 13 // 1Byte 0 -127 0x00-0x7F 14 // 2Byte 128-32639 0x80 0x01 - 0xFF 0x7F 15 byte byte2 = 0;

2、可变报头

协议信息:

1     // 协议信息
2     string p_str = "MQTT";
3     byte[] p_bytes = Encoding.ASCII.GetBytes(p_str);
4     byte_list.Add((byte)(p_bytes.Length / 256));
5     byte_list.Add((byte)(p_bytes.Length % 256));
6     byte_list.AddRange(p_bytes);
7     // 版本号 
8     byte_list.Add(0x04); // 3.1.1版本协议,如果是5.0版本协议:0x05

 连接标志:

 1     // 连接标志:一个字节
 2     {
 3         byte flag = 0;
 4         flag |= 128;// 将用户名标记置1
 5         flag |= 64;// 将密码标记置1
 6 
 7         // Will (对应2 3 4 5)
 8         flag |= 4;// 将使用消息标记置1
 9         flag |= 2; // 清理会话,将Clean Session标记置1
10         byte_list.Add(flag);
11     }

KeepAlive:

1     // Keep Alive(秒)
2     ushort second = 100;
3     byte_list.Add((byte)(second / 256));
4     byte_list.Add((byte)(second % 256));

3、载荷内容,负载信息

 1     // ClientId
 2     string client_id = "XFEX";
 3     byte[] ci_bytes = Encoding.ASCII.GetBytes(client_id);
 4     byte_list.Add((byte)(ci_bytes.Length / 256));
 5     byte_list.Add((byte)(ci_bytes.Length % 256));
 6     byte_list.AddRange(ci_bytes);
 7 
 8     // 根据可变报头中的标记位
 9     string will_topic_str = "test";
10     byte[] wt_bytes = Encoding.ASCII.GetBytes(will_topic_str);
11     byte_list.Add((byte)(wt_bytes.Length / 256));
12     byte_list.Add((byte)(wt_bytes.Length % 256));
13     byte_list.AddRange(wt_bytes);
14 
15     // 添加will消息信息
16     string will_msg_str = "xiaokache";
17     byte[] wm_bytes = Encoding.ASCII.GetBytes(will_msg_str);
18     byte_list.Add((byte)(wm_bytes.Length / 256));
19     byte_list.Add((byte)(wm_bytes.Length % 256));
20     byte_list.AddRange(wm_bytes);
21 
22     // 添加用户名信息
23     string user_str = "admin";
24     byte[] u_bytes = Encoding.ASCII.GetBytes(user_str);
25     byte_list.Add((byte)(u_bytes.Length / 256));
26     byte_list.Add((byte)(u_bytes.Length % 256));
27     byte_list.AddRange(u_bytes);
28 
29     // 添加密码信息
30     string pwd_str = "123456";
31     byte[] p_bytes = Encoding.ASCII.GetBytes(pwd_str);
32     byte_list.Add((byte)(p_bytes.Length / 256));
33     byte_list.Add((byte)(p_bytes.Length % 256));
34     byte_list.AddRange(p_bytes);

 

测试:

 

posted @ 2023-08-12 18:21  逆风起降  阅读(83)  评论(0)    收藏  举报