⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 messages.cs

📁 这是一个很好的收发短信程序 需要都尽情享用
💻 CS
📖 第 1 页 / 共 3 页
字号:

//CMPP 消息定义
namespace Glenet.CMPP.Messages
{
	using System;
	using System.Security.Cryptography;
	using System.Text;

	public class CMPP_Request
	{

	}
	public class CMPP_Response
	{

	}
	public enum CMPP_Command_Id : uint
	{
		CMPP_CONNECT = 0x00000001 //请求连接
			,
		CMPP_CONNECT_RESP = 0x80000001 //请求连接应答
			,
		CMPP_TERMINATE = 0x00000002 //终止连接
			,
		CMPP_TERMINATE_RESP = 0x80000002 //终止连接应答
			,
		CMPP_SUBMIT = 0x00000004 //提交短信
			,
		CMPP_SUBMIT_RESP = 0x80000004 //提交短信应答
			,
		CMPP_DELIVER = 0x00000005 //短信下发
			,
		CMPP_DELIVER_RESP = 0x80000005 //下发短信应答
			,
		CMPP_QUERY = 0x00000006 //发送短信状态查询
			,
		CMPP_QUERY_RESP = 0x80000006 //发送短信状态查询应答
			,
		CMPP_CANCEL = 0x00000007 //删除短信
			,
		CMPP_CANCEL_RESP = 0x80000007 //删除短信应答
			,
		CMPP_ACTIVE_TEST = 0x00000008 //激活测试
			,
		CMPP_ACTIVE_TEST_RESP = 0x80000008 //激活测试应答
			,
		CMPP_FWD = 0x00000009 //消息前转
			,
		CMPP_FWD_RESP = 0x80000009 //消息前转应答
			,
		CMPP_MT_ROUTE = 0x00000010 //MT路由请求
			,
		CMPP_MT_ROUTE_RESP = 0x80000010 //MT路由请求应答
			,
		CMPP_MO_ROUTE = 0x00000011 //MO路由请求
			,
		CMPP_MO_ROUTE_RESP = 0x80000011 //MO路由请求应答
			,
		CMPP_GET_MT_ROUTE = 0x00000012 //获取MT路由请求
			,
		CMPP_GET_MT_ROUTE_RESP = 0x80000012 //获取MT路由请求应答
			,
		CMPP_MT_ROUTE_UPDATE = 0x00000013 //MT路由更新
			,
		CMPP_MT_ROUTE_UPDATE_RESP = 0x80000013 //MT路由更新应答
			,
		CMPP_MO_ROUTE_UPDATE = 0x00000014 //MO路由更新
			,
		CMPP_MO_ROUTE_UPDATE_RESP = 0x80000014 //MO路由更新应答
			,
		CMPP_PUSH_MT_ROUTE_UPDATE = 0x00000015 //MT路由更新
			,
		CMPP_PUSH_MT_ROUTE_UPDATE_RESP = 0x80000015 //MT路由更新应答
			,
		CMPP_PUSH_MO_ROUTE_UPDATE = 0x00000016 //MO路由更新
			,
		CMPP_PUSH_MO_ROUTE_UPDATE_RESP = 0x80000016 //MO路由更新应答
			,
		CMPP_GET_MO_ROUTE = 0x00000017 //获取MO路由请求
			,
		CMPP_GET_MO_ROUTE_RESP = 0x80000017 //获取MO路由请求应答
	}

	public class Util
	{
		public static string Get_MMDDHHMMSS_String(DateTime dt)
		{
			string s = dt.Month.ToString().PadLeft(2, '0');
			s += dt.Day.ToString().PadLeft(2, '0');
			s += dt.Hour.ToString().PadLeft(2, '0');
			s += dt.Minute.ToString().PadLeft(2, '0');
			s += dt.Second.ToString().PadLeft(2, '0');
			return (s);
		}
		public static string Get_YYYYMMDD_String(DateTime dt)
		{
			string s = dt.Year.ToString().PadLeft(4, '0');
			s += dt.Month.ToString().PadLeft(2, '0');
			s += dt.Day.ToString().PadLeft(2, '0');
			return (s);
		}
	}

	public class MessageHeader //消息头
	{
		public const int Length = 4 + 4 + 4;
		//private byte[] _bytes = new byte[MessageHeader.Length];
		public CMPP_Command_Id Command_Id
		{
			get
			{
				return this._Command_Id;
			}
		}

		public uint Sequence_Id
		{
			get
			{
				return this._Sequence_Id;
			}
            set
            {
                _Sequence_Id = value;
            }
            
		}

		public uint Total_Length
		{
			get
			{
				return this._Total_Length;
			}
		}

		//private CMPP_Command_Id _Command_Id;
		//private uint _Sequence_Id;
		//private uint _Total_Length;

		uint _Total_Length; // 4 Unsigned Integer 消息总长度(含消息头及消息体)
		CMPP_Command_Id _Command_Id; // 4 Unsigned Integer 命令或响应类型
		uint _Sequence_Id; // 4 Unsigned Integer 消息流水号,顺序累加,步长为1,循环使用(一对请求和应答消息的流水号必须相同)

		public MessageHeader(uint Total_Length, CMPP_Command_Id Command_Id, uint Sequence_Id) //发送前
		{
			this._Command_Id = Command_Id;
			this._Sequence_Id = Sequence_Id;
			this._Total_Length = Total_Length;
		}

		public MessageHeader(byte[] bytes)
		{
			byte[] buffer = new byte[4];
			Buffer.BlockCopy(bytes, 0, buffer, 0, buffer.Length);
			Array.Reverse(buffer);
			this._Total_Length = BitConverter.ToUInt32(buffer, 0);

			Buffer.BlockCopy(bytes, 4, buffer, 0, buffer.Length);
			Array.Reverse(buffer);
			this._Command_Id = (CMPP_Command_Id) (BitConverter.ToUInt32(buffer, 0));

			Buffer.BlockCopy(bytes, 8, buffer, 0, buffer.Length);
			Array.Reverse(buffer);
			this._Sequence_Id = BitConverter.ToUInt32(buffer, 0);
		}


		public byte[] ToBytes()
		{
			byte[] bytes = new byte[MessageHeader.Length];

			byte[] buffer = BitConverter.GetBytes(this._Total_Length);
			Array.Reverse(buffer);
			Buffer.BlockCopy(buffer, 0, bytes, 0, 4);

			buffer = BitConverter.GetBytes((uint) this._Command_Id);
			Array.Reverse(buffer);
			Buffer.BlockCopy(buffer, 0, bytes, 4, 4);

			buffer = BitConverter.GetBytes(this._Sequence_Id);
			Array.Reverse(buffer);
			Buffer.BlockCopy(buffer, 0, bytes, 8, 4);

			return bytes;
		}

	}

	public class CMPP_CONNECT : CMPP_Request
	{
		public const int BodyLength = 6 + 16 + 1 + 4;

		string _Source_Addr; // 6 Octet String 源地址,此处为SP_Id,即SP的企业代码。
		private string _Password;
		byte[] _AuthenticatorSource; // 16 Octet String 用于鉴别源地址。其值通过单向MD5 hash计算得出,表示如下:
		//   AuthenticatorSource =
		//   MD5(Source_Addr+9 字节的0 +shared secret+timestamp)
		//   Shared secret 由中国移动与源地址实体事先商定,timestamp格式为:MMDDHHMMSS,即月日时分秒,10位。
		uint _Version; // 1 Unsigned Integer 双方协商的版本号(高位4bit表示主版本号,低位4bit表示次版本号),对于3.0的版本,高4bit为3,低4位为0
		uint _Timestamp; // 4 Unsigned Integer 时间戳的明文,由客户端产生,格式为MMDDHHMMSS,即月日时分秒,10位数字的整型,右对齐 。

		private MessageHeader _Header;

		public MessageHeader Header
		{
			get
			{
				return this._Header;
			}
		}

		public byte[] AuthenticatorSource
		{
			get
			{
				return this._AuthenticatorSource;
			}
		}

		public CMPP_CONNECT(string Source_Addr, string Password, DateTime Timestamp, uint Version)
		{
			this._Header = new MessageHeader(MessageHeader.Length + BodyLength, CMPP_Command_Id.CMPP_CONNECT, 1);

			this._Source_Addr = Source_Addr;
			this._Password = Password;

			string s = Util.Get_MMDDHHMMSS_String(Timestamp);
			this._Timestamp = UInt32.Parse(s);

			byte[] buffer = new byte[6 + 9 + this._Password.Length + 10];
			Encoding.ASCII.GetBytes(this._Source_Addr).CopyTo(buffer, 0);
			Encoding.ASCII.GetBytes(this._Password).CopyTo(buffer, 6 + 9);
			Encoding.ASCII.GetBytes(s).CopyTo(buffer, 6 + 9 + this._Password.Length);
			this._AuthenticatorSource = new MD5CryptoServiceProvider().ComputeHash(buffer, 0, buffer.Length);

			this._Version = Version;
		}

		public byte[] ToBytes()
		{
			byte[] bytes = new byte[MessageHeader.Length + BodyLength];
			int i = 0;

			//header 12
			byte[] buffer = this._Header.ToBytes();
			Buffer.BlockCopy(buffer, 0, bytes, 0, buffer.Length);

			//Source_Addr 6
			i += MessageHeader.Length;
			buffer = Encoding.ASCII.GetBytes(this._Source_Addr);
			Buffer.BlockCopy(buffer, 0, bytes, i, 6);

			//AuthenticatorSource 16
			i += 6;
			buffer = this._AuthenticatorSource;
			Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length); //16

			//version 1
			i += 16;
			bytes[i++] = (byte) this._Version; //版本

			//Timestamp
			buffer = BitConverter.GetBytes(this._Timestamp);
			Array.Reverse(buffer);
			buffer.CopyTo(bytes, i);
			return (bytes);
		}
	}

	public class CMPP_CONNECT_RESP : CMPP_Response
	{
		MessageHeader _Header;
		public const int _FixedBodyLength = 1 + 16 + 1;

		uint _Status; // 4 Unsigned Integer 状态
		//   0:正确
		//   1:消息结构错
		//   2:非法源地址
		//   3:认证错
		//   4:版本太高
		//   5~:其他错误
		byte[] _AuthenticatorISMG; // 16 Octet String ISMG认证码,用于鉴别ISMG。
		//   其值通过单向MD5 hash计算得出,表示如下:
		//   AuthenticatorISMG =MD5(Status+AuthenticatorSource+shared secret),Shared secret 由中国移动与源地址实体事先商定,AuthenticatorSource为源地址实体发送给ISMG的对应消息CMPP_Connect中的值。
		//    认证出错时,此项为空。
		uint _Version; // 1 Unsigned Integer 服务器支持的最高版本号,对于3.0的版本,高4bit为3,低4位为0

		public byte[] AuthenticatorISMG
		{
			get
			{
				return this._AuthenticatorISMG;
			}
		}

		public uint Status
		{
			get
			{
				return this._Status;
			}
		}

		public uint Version
		{
			get
			{
				return this._Version;
			}
		}

		public MessageHeader Header
		{
			get
			{
				return this._Header;
			}
		}

		public CMPP_CONNECT_RESP(byte[] bytes)
		{
			//header 12
			int i = 0;
			byte[] buffer = new byte[MessageHeader.Length];
			Buffer.BlockCopy(bytes, 0, buffer, 0, buffer.Length);
			this._Header = new MessageHeader(buffer);

			//status 4
			i += MessageHeader.Length;
			//buffer = new byte[4];
			//Array.Reverse(buffer);
			this._Status = bytes[i];//BitConverter.ToUInt32(buffer, 0);

			//AuthenticatorISMG 16
			i += 1;
			this._AuthenticatorISMG = new byte[16];
			Buffer.BlockCopy(bytes, MessageHeader.Length + 1, this._AuthenticatorISMG, 0, this._AuthenticatorISMG.Length);

			//version
			i += 16;
			this._Version = bytes[i];
		}

	}

	public class CMPP_SUBMIT : CMPP_Request
	{
		public int _BodyLength;
		//without _Dest_terminal_Id Msg_Content 
		public const int FixedBodyLength = 8
			+ 1
			+ 1
			+ 1
			+ 1
			+ 10
			+ 1
			+ 21//32
			//+ 1
			+ 1
			+ 1
			+ 1
			+ 6
			+ 2
			+ 6
			+ 17
			+ 17
			+ 21
			+ 1
			//+ 21*DestUsr_tl
			+ 1
			//+ Msg_length
			+ 8;//20;

		uint _Msg_Id; // 8 Unsigned Integer 信息标识。
		uint _Pk_total; // 1 Unsigned Integer 相同Msg_Id的信息总条数,从1开始。
		uint _Pk_number; // 1 Unsigned Integer 相同Msg_Id的信息序号,从1开始。
		uint _Registered_Delivery; // 1 Unsigned Integer 是否要求返回状态确认报告:
		//   0:不需要;
		//   1:需要。
		uint _Msg_level; // 1 Unsigned Integer 信息级别。
		string _Service_Id; // 10 Octet String 业务标识,是数字、字母和符号的组合。
		uint _Fee_UserType; // 1 Unsigned Integer 计费用户类型字段:
		//   0:对目的终端MSISDN计费;
		//   1:对源终端MSISDN计费;
		//   2:对SP计费;
		//   3:表示本字段无效,对谁计费参见Fee_terminal_Id字段。
		string _Fee_terminal_Id; // 32 Octet String 被计费用户的号码,当Fee_UserType为3时该值有效,当Fee_UserType为0、1、2时该值无意义。
		//uint _Fee_terminal_type; // 1 Unsigned Integer 被计费用户的号码类型,0:真实号码;1:伪码。
		uint _TP_pId; // 1 Unsigned Integer GSM协议类型。详细是解释请参考GSM03.40中的9.2.3.9。
		uint _TP_udhi; // 1 Unsigned Integer GSM协议类型。详细是解释请参考GSM03.40中的9.2.3.23,仅使用1位,右对齐。
		uint _Msg_Fmt; // 1 Unsigned Integer 信息格式:
		//   0:ASCII串;
		//   3:短信写卡操作;
		//   4:二进制信息;
		//   8:UCS2编码;
		//   15:含GB汉字。。。。。。
		string _Msg_src; // 6 Octet String 信息内容来源(SP_Id)。
		string _FeeType; // 2 Octet String 资费类别:
		//   01:对"计费用户号码"免费;
		//   02:对"计费用户号码"按条计信息费;
		//   03:对"计费用户号码"按包月收取信息费。
		string _FeeCode; // 6 Octet String 资费代码(以分为单位)。
		string _ValId_Time; // 17 Octet String 存活有效期,格式遵循SMPP3.3协议。
		string _At_Time; // 17 Octet String 定时发送时间,格式遵循SMPP3.3协议。
		string _Src_Id; // 21 Octet String 源号码。SP的服务代码或前缀为服务代码的长号码, 网关将该号码完整的填到SMPP协议Submit_SM消息相应的source_addr字段,该号码最终在用户手机上显示为短消息的主叫号码。
		uint _DestUsr_tl; // 1 Unsigned Integer 接收信息的用户数量(小于100个用户)。
		string[] _Dest_terminal_Id; // 32*DestUsr_tl Octet String 接收短信的MSISDN号码。


		//uint _Dest_terminal_type; // 1 Unsigned Integer 接收短信的用户的号码类型,0:真实号码;1:伪码。
		uint _Msg_Length; // 1 Unsigned Integer 信息长度(Msg_Fmt值为0时:<160个字节;其它<=140个字节),取值大于或等于0。
		string _Msg_Content; // Msg_length Octet String 信息内容。
		string _LinkID; // 20 Octet String 点播业务使用的LinkID,非点播类业务的MT流程不使用该字段。

		public MessageHeader _Header;

		public CMPP_SUBMIT()
		{
			//this._Header = new MessageHeader(MessageHeader._Length + _FixedBodyLength, CMPP_Command_Id.CMPP_SUBMIT, 1);
		}
        public byte[] ToBytes()
        {
            return ToBytes(1);
        }
		public byte[] ToBytes(uint squentID)
		{
			//Msg_Length Msg_Content
			byte[] buf;
			switch (this._Msg_Fmt)
			{
				case 8:
					buf = Encoding.BigEndianUnicode.GetBytes(this._Msg_Content);
					break;
				case 15: //gb2312
					buf = Encoding.GetEncoding("gb2312").GetBytes(this._Msg_Content);
					break;
				case 0: //ascii
				case 3: //短信写卡操作
				case 4: //二进制信息
				default:
					buf = Encoding.ASCII.GetBytes(this._Msg_Content);
					break;
			}

			this._Msg_Length = (uint) buf.Length;
			//this._BodyLength = (int) (FixedBodyLength + 32 * this._Dest_terminal_Id.Length + this._Msg_Length);
			this._BodyLength = (int) (FixedBodyLength + 21 * this._Dest_terminal_Id.Length + this._Msg_Length);
			byte[] bytes = new byte[MessageHeader.Length + this._BodyLength];

			int i = 0;

			byte[] buffer = new byte[MessageHeader.Length];
			//header
            this._Header = new MessageHeader((uint)(MessageHeader.Length + this._BodyLength), CMPP_Command_Id.CMPP_SUBMIT, squentID);
			buffer = this._Header.ToBytes();
			Buffer.BlockCopy(buffer, 0, bytes, 0, buffer.Length);
			i += MessageHeader.Length;

			//Msg_Id //8 [12,19]
			buffer = new byte[8];
			buffer = BitConverter.GetBytes(this._Msg_Id);
			Array.Reverse(buffer);
			Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length); //10 //[24,33]

			//_Pk_total
			i += 8;
			bytes[i++] = (byte) this._Pk_total; //[20,20]
			bytes[i++] = (byte) this._Pk_number; //[21,21]
			bytes[i++] = (byte) this._Registered_Delivery; //[22,22]
			bytes[i++] = (byte) this._Msg_level; //[23,23]

			//Service_Id
			buffer = Encoding.ASCII.GetBytes(this._Service_Id);
			Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length); //10 //[24,33]

			//Fee_UserType
			i += 10;
			bytes[i++] = (byte) this._Fee_UserType; //[34,34]

			//Fee_terminal_Id
			buffer = Encoding.ASCII.GetBytes(this._Fee_terminal_Id);
			Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length); //32 //[35,66]

			//Fee_terminal_type
			i += 21;//32;
			//*********************
			//bytes[i++] = (byte) this._Fee_terminal_type; //[67,67]
			bytes[i++] = (byte) this._TP_pId; //[68,68]
			bytes[i++] = (byte) this._TP_udhi; //[69,69]
			bytes[i++] = (byte) this._Msg_Fmt; //[70,70]

			//Msg_src
			buffer = Encoding.ASCII.GetBytes(this._Msg_src);
			Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length); //6 //[71,76]

			//FeeType
			i += 6;
			buffer = Encoding.ASCII.GetBytes(this._FeeType);
			Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length); //2 //[77,78]

			//FeeCode
			i += 2;
			buffer = Encoding.ASCII.GetBytes(this._FeeCode);
			Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length); //6 //[79,84]

			//ValId_Time
			i += 6;
//			buffer = Encoding.ASCII.GetBytes(this._ValId_Time);
//			Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length); //17 //[85,101]

			//At_Time
			i += 17;
//			buffer = Encoding.ASCII.GetBytes(this._At_Time);
//			Buffer.BlockCopy(buffer , 0, bytes, i, buffer.Length); //17 //[102,118]

			//Src_Id
			i += 17;
			buffer = Encoding.ASCII.GetBytes(this._Src_Id);
			Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length); //21 //[119,139]

			//DestUsr_tl
			i += 21;
			this._DestUsr_tl = (uint) this._Dest_terminal_Id.Length;
			bytes[i++] = (byte) this._DestUsr_tl; //[140,140]

			//Dest_terminal_Id
			foreach (string s in this._Dest_terminal_Id)
			{
				buffer = Encoding.ASCII.GetBytes(s);
				Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length);
				//i += 32;
				i += 21;
			}

			//Dest_terminal_type
			//*****************
			//bytes[i++] = (byte) this._Dest_terminal_type;
			//Msg_Length
			bytes[i++] = (byte) this._Msg_Length;

			//Msg_Content
			//buffer = Encoding.
			Buffer.BlockCopy(buf, 0, bytes, i, buf.Length);

			//LinkID
			i += (int) this._Msg_Length;
			buffer = Encoding.ASCII.GetBytes(this._LinkID);
			Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length); //20
			return bytes;
		}

		public uint Msg_Id
		{
			get
			{
				return this._Msg_Id;
			}
			set
			{
				this._Msg_Id = value;
			}
		}

		public uint Pk_total
		{
			get
			{
				return this._Pk_total;
			}
			set
			{
				this._Pk_total = value;
			}
		}

		public uint Pk_number
		{
			get
			{
				return this._Pk_number;
			}
			set
			{
				this._Pk_number = value;
			}
		}

		public uint Registered_Delivery
		{
			get
			{
				return this._Registered_Delivery;
			}
			set
			{
				this._Registered_Delivery = value;
			}
		}

		public uint Msg_level
		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -