1. 程式人生 > >.Net/C# 實現 中國移動 CMPP v3.0 ISMG SP 收發簡訊的 SP 客戶端 (CMPP SP Client)

.Net/C# 實現 中國移動 CMPP v3.0 ISMG SP 收發簡訊的 SP 客戶端 (CMPP SP Client)

 /* 
.Net/C# 實現 中國移動 CMPP v3.0 ISMG <-> SP 收發簡訊的 SP 客戶端 (CMPP SP Client) 
本程式嚴格按 
《中國行動通訊企業標準》之《中國行動通訊網際網路簡訊閘道器介面協議(China Mobile Point to Point)》(版本號: 3.0.0) 
即: CMPP v3.0.0 
http://www.spzone.net/protocol/CMPPV3.0.rar 
文件,實現了下面訊息的定義及其相關協議級互動:

8.4 業務提供商 (SP) 與網際網路簡訊閘道器 (ISMG) 間的訊息定義 8 
8.4.1 SP 請求連線到 ISMG(CMPP_CONNECT) 操作 8 
8.4.1.1 CMPP_CONNECT 訊息定義 (SP -> ISMG) 8 
8.4.1.2 CMPP_CONNECT_RESP訊息定義 (ISMG -> SP) 9 
8.4.2 SP 或 ISMG 請求拆除連線 (CMPP_TERMINATE)操作 9 
8.4.2.1 CMPP_TERMINATE 訊息定義 (SP -> ISMG 或 ISMG -> SP) 9 
8.4.2.2 CMPP_TERMINATE_RESP 訊息定義 (SP -> ISMG 或 ISMG -> SP) 10 
8.4.3 SP 向 ISMG提交簡訊 (CMPP_SUBMIT) 操作 10 
8.4.3.1 CMPP_SUBMIT 訊息定義 (SP -> ISMG) 10 
8.4.3.2 CMPP_SUBMIT_RESP 訊息定義 (ISMG -> SP) 11 
8.4.5 ISMG 向 SP 送交簡訊 (CMPP_DELIVER) 操作 13 
8.4.5.1 CMPP_DELIVER 訊息定義 (ISMG -> SP) 13 
8.4.5.2 CMPP_DELIVER_RESP 訊息定義(SP -> ISMG) 16

可採用《中國行動通訊 CMPP v3.0 短訊息閘道器模擬器 v1.10》進行測試: 
下載於: 《北京風起水流軟體工作室》 
http://www.zealware.com/download/cmpp3pro.rar

本程式以熟悉理解 CMPP 3.0 協議為主要目的,只將 "訊息定義" 物件化,其相關協議級互動並未作更深層次的 OO! 
也暫無任何錯誤處理程式! 
訊息定義的所有欄位名稱及其資料型別均與上述之 CMPP v3.0.0 文件完全一致!

其間參閱過 [email protected] or [email protected] 大作(在此鳴謝): 
http://blog.csdn.net/shanhe/archive/2004/07/19/45383.aspx 
http://cnblogs.com/yexiong/articles/115330.aspx 

但其中有些訊息定義位元組錯位,因此不能正常互動?!且物件化層次較高,不利於理解協議本身! 
遂自己動手,豐衣足食,實現部分主要協議(SP 收發簡訊):

playyuer$at$microshaoft.com Invent. 
*/

//CMPP 訊息定義 
namespace Microshaoft.CMPP.Messages 

 using System; 
 using System.Security.Cryptography; 
 using System.Text;

 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 GetTimestampString(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 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; 
   } 
  }

  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 //: ICMPP_Message 
 { 
  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.GetTimestampString(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 //: ICMPP_Message 
 { 
  MessageHeader _Header; 
  public const int _FixedBodyLength = 4 + 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]; 
   Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length); 
   Array.Reverse(buffer); 
   this._Status = BitConverter.ToUInt32(buffer, 0);

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

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

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

  ulong _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流程不使用該欄位。

  MessageHeader _Header;

  public CMPP_SUBMIT() 
  { 
   //this._Header = new MessageHeader(MessageHeader._Length + _FixedBodyLength, CMPP_Command_Id.CMPP_SUBMIT, 1); 
  }

  public byte[] ToBytes() 
  { 
   //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); 
   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, 0); 
   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 += 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; 
   }

   //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 ulong 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 
  { 
   get 
   { 
    return this._Msg_level; 
   } 
   set 
   { 
    this._Msg_level = value; 
   } 
  }

  public string Service_Id 
  { 
   get 
   { 
    return this._Service_Id; 
   } 
   set 
   { 
    this._Service_Id = value; 
   } 
  }

  public uint Fee_UserType 
  { 
   get 
   { 
    return this._Fee_UserType; 
   } 
   set 
   { 
    this._Fee_UserType = value; 
   } 
  }

  public string Fee_terminal_Id 
  { 
   get 
   { 
    return this._Fee_terminal_Id; 
   } 
   set 
   { 
    this._Fee_terminal_Id = value; 
   } 
  }

  public uint Fee_terminal_type 
  { 
   get 
   { 
    return this._Fee_terminal_type; 
   } 
   set 
   { 
    this._Fee_terminal_type = value; 
   } 
  }

  public uint Tp_pId 
  { 
   get 
   { 
    return this._TP_pId; 
   } 
   set 
   { 
    this._TP_pId = value; 
   } 
  }

  public uint Tp_udhi 
  { 
   get 
   { 
    return this._TP_udhi; 
   } 
   set 
   { 
    this._TP_udhi = value; 
   } 
  }

  public uint Msg_Fmt 
  { 
   get 
   { 
    return this._Msg_Fmt; 
   } 
   set 
   { 
    this._Msg_Fmt = value; 
   } 
  }

  public string Msg_src 
  { 
   get 
   { 
    return this._Msg_src; 
   } 
   set 
   { 
    _Msg_src = value; 
   } 
  }

  public string FeeType 
  { 
   get 
   { 
    return this._FeeType; 
   } 
   set 
   { 
    this._FeeType = value; 
   } 
  }

  public string FeeCode 
  { 
   get 
   { 
    return this._FeeCode; 
   } 
   set 
   { 
    this._FeeCode = value; 
   } 
  }

  public string ValId_Time 
  { 
   get 
   { 
    return this._ValId_Time; 
   } 
   set 
   { 
    this._ValId_Time = value; 
   } 
  }

  public string At_Time 
  { 
   get 
   { 
    return this._At_Time; 
   } 
   set 
   { 
    this._At_Time = value; 
   } 
  }

  public string Src_Id 
  { 
   get 
   { 
    return this._Src_Id; 
   } 
   set 
   { 
    this._Src_Id = value; 
   } 
  }

  public uint DestUsr_tl 
  { 
   get 
   { 
    return this._DestUsr_tl; 
   } 
   set 
   { 
    this._DestUsr_tl = value; 
   } 
  }

  public string[] Dest_terminal_Id 
  { 
   get 
   { 
    return this._Dest_terminal_Id; 
   } 
   set 
   { 
    this._Dest_terminal_Id = value; 
   } 
  }

  public uint Dest_terminal_type 
  { 
   get 
   { 
    return this._Dest_terminal_type; 
   } 
   set 
   { 
    this._Dest_terminal_type = value; 
   } 
  }

  public uint Msg_Length 
  { 
   get 
   { 
    return this._Msg_Length; 
   } 
   set 
   { 
    this._Msg_Length = value; 
   } 
  }

  public string Msg_Content 
  { 
   get 
   { 
    return this._Msg_Content; 
   } 
   set 
   { 
    this._Msg_Content = value; 
   } 
  }

  public string LinkId 
  { 
   get 
   { 
    return this._LinkID; 
   } 
   set 
   { 
    this._LinkID = value; 

相關推薦

.Net/C# 實現 中國移動 CMPP v3.0 ISMG SP 收發簡訊SP 客戶 (CMPP SP Client)

 /*  .Net/C# 實現 中國移動 CMPP v3.0 ISMG <-> SP 收發簡訊的 SP 客戶端 (CMPP SP Client)  本程式嚴格按  《中國行動通訊企業標準》之《中國行動通訊網際網路簡訊閘道器介面協議(China Mob

[原始碼和報告分享] C#實現的基於SMTP協議的E-MAIL電子郵件傳送客戶軟體

利用SMTP和Pop協議從底層開發了這個軟體。SMTP全稱是簡單郵件傳輸協議,它專門用來發送郵件用的。Pop全稱是郵局協議,是專門用於接收郵件的。我主要是負責如何實現傳送郵件功能的。MailSend名稱空間是我整個程式的核心。它包括兩個類。在SmtpMail的類中包含了一個SendMail的方法,它

Springboot 整合 中國移動MAS HTTP1.0 實現簡訊傳送服務(二)

原因:身份驗證傳入的引數包含中文企業名,因為本地編碼格式是支援中文的;而客戶的伺服器中文卻亂碼,導致傳給中國移動MAS伺服器的是亂碼的資訊。 解決:非常簡單,將中文資訊轉為UTF-8。例如(%E5%8D%9A%E5%AE%A2%E5%9B%AD) // 身份驗證方法 public s

c實現坦克移動

背景 clock ret tex ase oid window set cdir #include<Windows.h> #include <stdio.h> #include<stdlib.h> #include <conio.h

RDIFramework.NET ━ .NET快速資訊化系統開發框架 V3.0 版本強勢釋出

      繼上個版本“RDIFramework.NET V2.9版本”的推出,受到了重多客戶的認可與選擇,V2.9版本是非常成功與穩定的版本,感謝大家的認可與長期以來的關注與支援。V3.0版本在V2.9版本的基礎上做了重大更新,如:新增了“序列管理”、“系統引數管理”、“查

RDIFramework.NET ━ .NET快速資訊化系統開發框架 V3.0 版新增查詢引擎管理

欲瞭解V3.0版本的相關內容可檢視下面的連結地址。在V3.0版本的Web(Mvc、WebForm)與WinForm中我們新增了“查詢引擎管理”模組。主要分為兩部分”查詢引擎管理“與”查詢引定義“。”查詢引擎管理“主要是對整個系統的查詢引擎定義進行分類管理,使用者可以對整個系統

.Net(C#)實現非同步程式設計

最近編寫了一個檢查伺服器叢集的客戶端程式,用於檢查API介面是否可用,由於當時沒有使用多執行緒技術,所有操作均在主程序中執行,這樣就導致了2個問題: 1)由於要傳送HTTP請求,導致主程序無響應,UI卡死 2)使用迴圈輪詢叢集的伺服器列表,逐個請求傳送到伺服器,時間複雜度為

.net C#實現登入介面並進行跳轉

登入介面: Userloagin.aspx <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Userloagin.aspx.cs" Inherits="UserLogin.Userloagin" %

C#/.NET基於Topshelf建立Windows服務的守護程式作為服務啟動的客戶桌面程式不顯示UI介面的問題分析和解決方案

本文首發於:碼友網--一個專注.NET/.NET Core開發的程式設計愛好者社群。 文章目錄 C#/.NET基於Topshelf建立Windows服務的系列文章目錄: C#/.NET基於Topshelf建立Windows服務程式及服務的安裝和解除安裝 (1) 在C#/.NET應用程式開發中建立一個基於To

C#Socket通訊基礎(非同步Socket通訊TCP)伺服器與客戶

一、效果圖 二、伺服器端程式碼(原始碼下載地址:https://download.csdn.net/download/xiaochenxihua/10748789) using System; using System.Collections.Generic; using System

Jedis 2.9.1、2.10.0 與 3.0.0 釋出,Redis 的 Java 客戶

   Jedis 2.9.1、2.10.0 與 3.0.0 釋出了,Jedis 是 Redis 的 Java 客戶端,它易於使用,與 Redis 2.8.x 和 3.x.x 完全相容。 2.9.1 與 2.10.0 更新: JedisCluster 掃描 bug 修復&nb

Redis 5.0 Cluster叢集帶認證及客戶連線

Redis在3.0版正式引入redis-cluster叢集這個特性。Redis叢集是一個提供在多個Redis間節點間共享資料的程式集。Redis叢集是一個分散式(distributed)、容錯(fault-tolerant)的Redis記憶體K/V服務,叢集可以使用的功能是普通單機Redis所能使用的功能的一

【.NET Core專案實戰-統一認證平臺】第十章 授權篇-客戶授權

上篇文章介紹瞭如何使用Dapper持久化IdentityServer4(以下簡稱ids4)的資訊,並實現了sqlserver和mysql兩種方式儲存,本篇將介紹如何使用ids4進行客戶端授權。 .netcore專案實戰交流群(637326624),有興趣的朋友可以在群裡交流討論

OAuth 2.0系列教程(四) 客戶型別

作者:Jakob Jenkov   譯者:林浩    校對:郭蕾 OAuth 2.0客戶端角色被細分為一系列型別和配置,本節將闡述這些型別和配置。 OAuth 2.0規範定義了兩種客戶端型別: 保密的 公有的 保密的客戶端能夠對外部保持客戶端密碼保密。該客戶端密碼是由授權伺服器分配給客戶

Navicat連線MySQL8.0版本時 建議升級連線客戶

錯誤:Client does not support authentication protocol requested by server; consider upgrading MySQL client Mysql官方給出的兩種方案我嘗試了並沒有作用。 貼吧看一大

三、ESP8266LUA開發之建立TCP伺服器,實現socket通訊控制繼電器,串列埠,伺服器,客戶收發資料小感悟

8266做伺服器,實現TCP通訊 注,實際燒錄的時候會因為註釋過多造成燒錄不進去的情況,這個時候需要刪除註釋! 先來測試8266建立伺服器,並分得IP 燒錄時,先燒wifi.lua,然後再燒init.lua。 init.lua

RocketMQ最佳實踐(一)4.0版本/概念介紹/安裝除錯/客戶demo

為什麼選擇RocketMQ 我們來看看官方回答: “我們研究發現,對於ActiveMQ而言,隨著越來越多的使用queues和topics,其IO成為了瓶頸。某些情況下,消費者緩慢(消費能力不足)還會拖慢生產者(造成訊息阻塞)。雖然我們做了最大努力進行優化:節流、斷路器或者回

C++ Builder XE8 安卓開發之使用TIdThreadComponent控制元件接收客戶的資料

C++ Builder中自帶了indy10控制元件,由於indy10的TCPClient接收方式是阻塞式的,所以需要一個執行緒來接收資料。 indy10本身有一個執行緒控制元件: 把它放在介面中就可以使用了。 我是在OnRun函式中新增自己的程式碼,雖然可以成功執行,

live555實現Rtp碼流讀到一幀資料怎麼傳遞客戶

1)實現一個sink讀取Live555的一幀資料後,測試發現有的碼流sps,pps,I幀是單獨的資料包傳遞過來的,這樣的話,在sink裡面需要對這些資料進行組幀,live555有沒有功能可以自己將這些資料包組成一幀資料,並且自動新增00 00 00 01這樣的頭資訊呢,如果

SpringBootSecurity學習(17)前後分離版之 OAuth2.0 資料庫(JDBC)儲存客戶

自動批准授權碼 前面我們授權的流程中,第一步獲取授權碼的時候,都會經歷一個授權是否同意頁面: 這個流程就像第三方登入成功後,提問是否允許獲取暱稱和頭像資訊的頁面一樣,這個過程其實是可以自動同意的,需要在客戶端配置中,增加一個自動批准: 這樣我們申請授權碼直接就可以得到: 在流程需要自動完成的時候,