源代码:
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();}/// <summary>/// 向服务器端发送请求,使用socket连接请求/// </summary>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<byte> list = new List<byte>();list.Add(0x10);//===========可变报头+载荷部分==============List<byte> list2 = new List<byte>();//可变报头由以下组成:协议名(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位)//11000010byte flag = 0; //0000 0000flag |= 128; //1000 0000//flag |=128 ==> 1000 0000或运算flag |= 64; //0100 0000//flag |=64 ==>//1100 0000或运算flag |= 2; //0000 0010//flag |=2 ==>//1100 0010list2.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字节数组//UserNamestring userName = "JT";byte[] nameByte = Encoding.UTF8.GetBytes(userName);list2.Add((byte)(nameByte.Length / 256 % 256));list2.Add((byte)(nameByte.Length % 256));list2.AddRange(nameByte);//Passwordstring 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。<