MQTT分析——CONNECT为例子

 源代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net.Sockets;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Connect();
        }
        /// 
        /// 向服务器端发送请求,使用socket连接请求
        /// 
        static void Connect()
        {
            Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Connect("127.0.0.1", 1883);//TCP三次握手
            //发送MQTT的登录请求
            //固定报头
            //第一个字节8个位,(消息类型4个位,DUP位1个位,Qos2个位,Retain1个位)
            //请求,根据固定报文控制类型,第一个请求为 00010000,表示从客户端到服务器
            List list = new List();
            list.Add(0x10);

            //===========可变报头+载荷部分==============
            List list2 = new List();
            //可变报头由以下组成:协议名(MQTT)+协议级别+连接标志+保持连接
            string protocolName = "MQTT";
            byte[] probyet = Encoding.UTF8.GetBytes(protocolName);//MQTT对应的ascii码的十六进制
            //协议长度
            list2.Add((byte)(probyet.Length / 256 % 256));
            list2.Add((byte)(probyet.Length % 256));
            list2.AddRange(probyet);//协议名称

            list2.Add(0x04);//协议级别,只能是0x04
            //连接标志 一个字节(8位)
            //11000010
            byte flag = 0; //0000 0000
            flag |= 128;   //1000 0000
            //flag |=128 ==> 1000 0000或运算
            flag |= 64;    //0100 0000
            //flag |=64 ==>//1100 0000或运算
            flag |= 2;     //0000 0010
            //flag |=2  ==>//1100 0010
            list2.Add(flag);

            //keep alive保持连接
            int second = 100; //保持100秒,持续到150秒
            list2.Add((byte)(second / 256 % 256));
            list2.Add((byte)(second % 256));

            //有效载荷(客户端标识符,遗嘱主题,遗嘱消息,用户名,密码)
            string clientStr = "JTVL";
            byte[] idBytes = Encoding.UTF8.GetBytes(clientStr); //ID的字节数组
            int idBytesLen = idBytes.Length; //ID字节数组的长度
            list2.Add((byte)(idBytes.Length / 256 % 256));
            list2.Add((byte)(idBytesLen % 256));
            list2.AddRange(idBytes); //添加ID字节数组

            //UserName
            string userName = "JT";
            byte[] nameByte = Encoding.UTF8.GetBytes(userName);
            list2.Add((byte)(nameByte.Length / 256 % 256));
            list2.Add((byte)(nameByte.Length % 256));
            list2.AddRange(nameByte);
            //Password
            string passWord = "123";
            byte[] passByte = Encoding.UTF8.GetBytes(passWord);
            list2.Add((byte)(passByte.Length / 256 % 256));
            list2.Add((byte)(passByte.Length  % 256));
            list2.AddRange(passByte);

            //把可变报头+载荷部分加到固定报头的后面
            //添加固定报头的第二个字节
            list.Add((byte)(list2.Count));
            //添加
            list.AddRange(list2);

            //发送连接请求报文
            socket.Send(list.ToArray());

        }
    }
}

一、知识基础

1、C#的byte类型

在C#中,byte类型表示一个8位无符号整数(也称为字节)。由于它是无符号的,它的值范围是0到255,即 1111 1111

2、BitConverter.GetBytes

BitConverter.GetBytes(int) 的返回值为 byte数组 ,但是创建的数组容量为4个,如果不够会依次增加4个,返回的顺序是顺序。即:如果是 256 ,则为 1 0000 0000 ,也就是第二个数组的值为1,第一个数组为0 ,而第三和第四为0;如果是 1 ,则为 0000 0001 ,第二第三第四值为0。<

你可能感兴趣的:(windows,c#,网络协议)