C#實(shí)現(xiàn)CMPP3.0 ISMG SP客戶(hù)端(CMPP SP Client)

2010-08-28 10:50:44來(lái)源:西部e網(wǎng)作者:

Net/C# 實(shí)現(xiàn) 中國(guó)移動(dòng) CMPP v3.0 ISMG <-> SP 收發(fā)短信的 SP 客戶(hù)端 (CMPP SP Client)
本程序嚴(yán)格按
《中國(guó)移動(dòng)通信企業(yè)標(biāo)準(zhǔn)》之《中國(guó)移動(dòng)通信互聯(lián)網(wǎng)短信網(wǎng)關(guān)接口協(xié)議(China Mobile Point to Point)》(版本號(hào): 3.0.0)
即: CMPP v3.0.0
http://www.spzone.net/protocol/CMPPV3.0.rar
文檔,實(shí)現(xiàn)了下面消息的定義及其相關(guān)協(xié)議級(jí)交互:

8.4 業(yè)務(wù)提供商 (SP) 與互聯(lián)網(wǎng)短信網(wǎng)關(guān) (ISMG) 間的消息定義 8
8.4.1 SP 請(qǐng)求連接到 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 請(qǐng)求拆除連接 (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
8.4.7 鏈路檢測(cè) (CMPP_ACTIVE_TEST) 操作 17
8.4.7.1 CMPP_ACTIVE_TEST定義 (SP -> ISMG 或 ISMG <- SP) 17
8.4.7.2 CMPP_ACTIVE_TEST_RESP定義 (SP -> ISMG 或 ISMG <- SP) 17


可采用《中國(guó)移動(dòng)通信 CMPP v3.0 短消息網(wǎng)關(guān)模擬器 v1.10》進(jìn)行測(cè)試:
下載于: 《北京風(fēng)起水流軟件工作室》
http://www.zealware.com/download/cmpp3pro.rar

本程序以熟悉理解 CMPP 3.0 協(xié)議為主要目的,只將 "消息定義" 對(duì)象化,其相關(guān)協(xié)議級(jí)交互并未作更深層次的 OO!
也暫無(wú)任何錯(cuò)誤處理程序!
消息定義的所有字段名稱(chēng)及其數(shù)據(jù)類(lèi)型均與上述之 CMPP v3.0.0 文檔完全一致!

其間參閱過(guò) shanhe@CSDN or yexiong@cnBlogs 大作(在此謝):
http://blog.csdn.net/shanhe/archive/2004/07/19/45383.aspx
http://cnblogs.com/yexiong/articles/115330.aspx
但其中有些消息定義字節(jié)錯(cuò)位,因此不能正常交互?!且對(duì)象化層次較高,不利于理解協(xié)議本身!
遂自己動(dòng)手,豐衣足食,實(shí)現(xiàn)部分主要協(xié)議(SP 收發(fā)短信):

playyuer$at$microshaoft.com Invent.
*/

//CMPP 消息定義
namespace Microshaoft.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 //請(qǐng)求連接
  ,CMPP_CONNECT_RESP = 0x80000001 //請(qǐng)求連接應(yīng)答
  ,CMPP_TERMINATE = 0x00000002 //終止連接
  ,CMPP_TERMINATE_RESP = 0x80000002 //終止連接應(yīng)答
  ,CMPP_SUBMIT = 0x00000004 //提交短信
  ,CMPP_SUBMIT_RESP = 0x80000004 //提交短信應(yīng)答
  ,CMPP_DELIVER = 0x00000005 //短信下發(fā)
  ,CMPP_DELIVER_RESP = 0x80000005 //下發(fā)短信應(yīng)答
  ,CMPP_QUERY = 0x00000006 //發(fā)送短信狀態(tài)查詢(xún)
  ,CMPP_QUERY_RESP = 0x80000006 //發(fā)送短信狀態(tài)查詢(xún)應(yīng)答
  ,CMPP_CANCEL = 0x00000007 //刪除短信
  ,CMPP_CANCEL_RESP = 0x80000007 //刪除短信應(yīng)答
  ,CMPP_ACTIVE_TEST = 0x00000008 //激活測(cè)試
  ,CMPP_ACTIVE_TEST_RESP = 0x80000008 //激活測(cè)試應(yīng)答
  ,CMPP_FWD = 0x00000009 //消息前轉(zhuǎn)
  ,CMPP_FWD_RESP = 0x80000009 //消息前轉(zhuǎn)應(yīng)答
  ,CMPP_MT_ROUTE = 0x00000010 //MT路由請(qǐng)求
  ,CMPP_MT_ROUTE_RESP = 0x80000010 //MT路由請(qǐng)求應(yīng)答
  ,CMPP_MO_ROUTE = 0x00000011 //MO路由請(qǐng)求
  ,CMPP_MO_ROUTE_RESP = 0x80000011 //MO路由請(qǐng)求應(yīng)答
  ,CMPP_GET_MT_ROUTE = 0x00000012 //獲取MT路由請(qǐng)求
  ,CMPP_GET_MT_ROUTE_RESP = 0x80000012 //獲取MT路由請(qǐng)求應(yīng)答
  ,CMPP_MT_ROUTE_UPDATE = 0x00000013 //MT路由更新
  ,CMPP_MT_ROUTE_UPDATE_RESP = 0x80000013 //MT路由更新應(yīng)答
  ,CMPP_MO_ROUTE_UPDATE = 0x00000014 //MO路由更新
  ,CMPP_MO_ROUTE_UPDATE_RESP = 0x80000014 //MO路由更新應(yīng)答
  ,CMPP_PUSH_MT_ROUTE_UPDATE = 0x00000015 //MT路由更新
  ,CMPP_PUSH_MT_ROUTE_UPDATE_RESP = 0x80000015 //MT路由更新應(yīng)答
  ,CMPP_PUSH_MO_ROUTE_UPDATE = 0x00000016 //MO路由更新
  ,CMPP_PUSH_MO_ROUTE_UPDATE_RESP = 0x80000016 //MO路由更新應(yīng)答
  ,CMPP_GET_MO_ROUTE = 0x00000017 //獲取MO路由請(qǐng)求
  ,CMPP_GET_MO_ROUTE_RESP = 0x80000017 //獲取MO路由請(qǐng)求應(yīng)答
 }

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

  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 消息總長(zhǎng)度(含消息頭及消息體)
  CMPP_Command_Id _Command_Id; // 4 Unsigned Integer 命令或響應(yīng)類(lèi)型
  uint _Sequence_Id; // 4 Unsigned Integer 消息流水號(hào),順序累加,步長(zhǎng)為1,循環(huán)使用(一對(duì)請(qǐng)求和應(yīng)答消息的流水號(hào)必須相同)

  public MessageHeader(uint Total_Length, CMPP_Command_Id Command_Id, uint Sequence_Id) //發(fā)送前
  {
   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的企業(yè)代碼。
  private string _Password;
  byte[] _AuthenticatorSource; // 16 Octet String 用于鑒別源地址。其值通過(guò)單向MD5 hash計(jì)算得出,表示如下:
  //   AuthenticatorSource =
  //   MD5(Source_Addr+9 字節(jié)的0 +shared secret+timestamp)
  //   Shared secret 由中國(guó)移動(dòng)與源地址實(shí)體事先商定,timestamp格式為:MMDDHHMMSS,即月日時(shí)分秒,10位。
  uint _Version; // 1 Unsigned Integer 雙方協(xié)商的版本號(hào)(高位4bit表示主版本號(hào),低位4bit表示次版本號(hào)),對(duì)于3.0的版本,高4bit為3,低4位為0
  uint _Timestamp; // 4 Unsigned Integer 時(shí)間戳的明文,由客戶(hù)端產(chǎn)生,格式為MMDDHHMMSS,即月日時(shí)分秒,10位數(shù)字的整型,右對(duì)齊 。

  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 = 4 + 16 + 1;

  uint _Status; // 4 Unsigned Integer 狀態(tài)
  //   0:正確
  //   1:消息結(jié)構(gòu)錯(cuò)
  //   2:非法源地址
  //   3:認(rèn)證錯(cuò)
  //   4:版本太高
  //   5~:其他錯(cuò)誤
  byte[] _AuthenticatorISMG; // 16 Octet String ISMG認(rèn)證碼,用于鑒別ISMG。
  //   其值通過(guò)單向MD5 hash計(jì)算得出,表示如下:
  //   AuthenticatorISMG =MD5(Status+AuthenticatorSource+shared secret),Shared secret 由中國(guó)移動(dòng)與源地址實(shí)體事先商定,AuthenticatorSource為源地址實(shí)體發(fā)送給ISMG的對(duì)應(yīng)消息CMPP_Connect中的值。
  //    認(rèn)證出錯(cuò)時(shí),此項(xiàng)為空。
  uint _Version; // 1 Unsigned Integer 服務(wù)器支持的最高版本號(hào),對(duì)于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 : CMPP_Request
 {
  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 信息標(biāo)識(shí)。
  uint _Pk_total; // 1 Unsigned Integer 相同Msg_Id的信息總條數(shù),從1開(kāi)始。
  uint _Pk_number; // 1 Unsigned Integer 相同Msg_Id的信息序號(hào),從1開(kāi)始。
  uint _Registered_Delivery; // 1 Unsigned Integer 是否要求返回狀態(tài)確認(rèn)報(bào)告:
  //   0:不需要;
  //   1:需要。
  uint _Msg_level; // 1 Unsigned Integer 信息級(jí)別。
  string _Service_Id; // 10 Octet String 業(yè)務(wù)標(biāo)識(shí),是數(shù)字、字母和符號(hào)的組合。
  uint _Fee_UserType; // 1 Unsigned Integer 計(jì)費(fèi)用戶(hù)類(lèi)型字段:
  //   0:對(duì)目的終端MSISDN計(jì)費(fèi);
  //   1:對(duì)源終端MSISDN計(jì)費(fèi);
  //   2:對(duì)SP計(jì)費(fèi);
  //   3:表示本字段無(wú)效,對(duì)誰(shuí)計(jì)費(fèi)參見(jiàn)Fee_terminal_Id字段。
  string _Fee_terminal_Id; // 32 Octet String 被計(jì)費(fèi)用戶(hù)的號(hào)碼,當(dāng)Fee_UserType為3時(shí)該值有效,當(dāng)Fee_UserType為0、1、2時(shí)該值無(wú)意義。
  uint _Fee_terminal_type; // 1 Unsigned Integer 被計(jì)費(fèi)用戶(hù)的號(hào)碼類(lèi)型,0:真實(shí)號(hào)碼;1:偽碼。
  uint _TP_pId; // 1 Unsigned Integer GSM協(xié)議類(lèi)型。詳細(xì)是解釋請(qǐng)參考GSM03.40中的9.2.3.9。
  uint _TP_udhi; // 1 Unsigned Integer GSM協(xié)議類(lèi)型。詳細(xì)是解釋請(qǐng)參考GSM03.40中的9.2.3.23,僅使用1位,右對(duì)齊。
  uint _Msg_Fmt; // 1 Unsigned Integer 信息格式:
  //   0:ASCII串;
  //   3:短信寫(xiě)卡操作;
  //   4:二進(jìn)制信息;
  //   8:UCS2編碼;
  //   15:含GB漢字。。。。。。
  string _Msg_src; // 6 Octet String 信息內(nèi)容來(lái)源(SP_Id)。
  string _FeeType; // 2 Octet String 資費(fèi)類(lèi)別:
  //   01:對(duì)"計(jì)費(fèi)用戶(hù)號(hào)碼"免費(fèi);
  //   02:對(duì)"計(jì)費(fèi)用戶(hù)號(hào)碼"按條計(jì)信息費(fèi);
  //   03:對(duì)"計(jì)費(fèi)用戶(hù)號(hào)碼"按包月收取信息費(fèi)。
  string _FeeCode; // 6 Octet String 資費(fèi)代碼(以分為單位)。
  string _ValId_Time; // 17 Octet String 存活有效期,格式遵循SMPP3.3協(xié)議。
  string _At_Time; // 17 Octet String 定時(shí)發(fā)送時(shí)間,格式遵循SMPP3.3協(xié)議。
  string _Src_Id; // 21 Octet String 源號(hào)碼。SP的服務(wù)代碼或前綴為服務(wù)代碼的長(zhǎng)號(hào)碼, 網(wǎng)關(guān)將該號(hào)碼完整的填到SMPP協(xié)議Submit_SM消息相應(yīng)的source_addr字段,該號(hào)碼最終在用戶(hù)手機(jī)上顯示為短消息的主叫號(hào)碼。
  uint _DestUsr_tl; // 1 Unsigned Integer 接收信息的用戶(hù)數(shù)量(小于100個(gè)用戶(hù))。
  string[] _Dest_terminal_Id; // 32*DestUsr_tl Octet String 接收短信的MSISDN號(hào)碼。


  uint _Dest_terminal_type; // 1 Unsigned Integer 接收短信的用戶(hù)的號(hào)碼類(lèi)型,0:真實(shí)號(hào)碼;1:偽碼。
  uint _Msg_Length; // 1 Unsigned Integer 信息長(zhǎng)度(Msg_Fmt值為0時(shí):<160個(gè)字節(jié);其它<=140個(gè)字節(jié)),取值大于或等于0。
  string _Msg_Content; // Msg_length Octet String 信息內(nèi)容。
  string _LinkID; // 20 Octet String 點(diǎn)播業(yè)務(wù)使用的LinkID,非點(diǎn)播類(lèi)業(yè)務(wù)的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: //短信寫(xiě)卡操作
    case 4: //二進(jìn)制信息
    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;
   }
  }


 }

 public class CMPP_SUBMIT_RESP : CMPP_Response
 {
  MessageHeader _Header;
  private uint _Msg_Id;
  private uint _Result;

  public const int BodyLength = 8 + 4;

  public uint Msg_Id
  {
   get
   {
    return this._Msg_Id;
   }
  }

  public uint Result
  {
   get
   {
    return this._Result;
   }
  }

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

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

   //Msg_Id
   i += MessageHeader.Length;
   buffer = new byte[8];
   Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length);
   Array.Reverse(buffer);
   this._Msg_Id = BitConverter.ToUInt32(buffer, 0);

   //Result
   i += 8;
   buffer = new byte[4];
   Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length);
   Array.Reverse(buffer);
   this._Result = BitConverter.ToUInt32(buffer, 0);
  }
 }


 public class CMPP_DELIVER : CMPP_Request
 {
  public ulong Msg_Id
  {
   get
   {
    return _Msg_Id;
   }
  }

  public string Dest_Id
  {
   get
   {
    return _Dest_Id;
   }
  }

  public string Service_Id
  {
   get
   {
    return _Service_Id;
   }
  }

  public uint TP_pid
  {
   get
   {
    return _TP_pid;
   }
  }

  public uint TP_udhi
  {
   get
   {
    return _TP_udhi;
   }
  }

  public uint Msg_Fmt
  {
   get
   {
    return _Msg_Fmt;
   }
  }

  public string Src_terminal_Id
  {
   get
   {
    return _Src_terminal_Id;
   }
  }

  public uint Src_terminal_type
  {
   get
   {
    return _Src_terminal_type;
   }
  }

  public uint Registered_Delivery
  {
   get
   {
    return _Registered_Delivery;
   }
  }

  public uint Msg_Length
  {
   get
   {
    return _Msg_Length;
   }
  }

  public string Msg_Content
  {
   get
   {
    return _Msg_Content;
   }
  }

  public string LinkId
  {
   get
   {
    return _LinkID;
   }
  }

  ulong _Msg_Id; // 8 Unsigned Integer 信息標(biāo)識(shí)。
  //   生成算法如下:
  //   采用64位(8字節(jié))的整數(shù):
  //   (1)????????? 時(shí)間(格式為MMDDHHMMSS,即月日時(shí)分秒):bit64~bit39,其中
  //   bit64~bit61:月份的二進(jìn)制表示;
  //   bit60~bit56:日的二進(jìn)制表示;
  //   bit55~bit51:小時(shí)的二進(jìn)制表示;
  //   bit50~bit45:分的二進(jìn)制表示;
  //   bit44~bit39:秒的二進(jìn)制表示;
  //   (2)????????? 短信網(wǎng)關(guān)代碼:bit38~bit17,把短信網(wǎng)關(guān)的代碼轉(zhuǎn)換為整數(shù)填寫(xiě)到該字段中;
  //   (3)????????? 序列號(hào):bit16~bit1,順序增加,步長(zhǎng)為1,循環(huán)使用。
  //   各部分如不能填滿(mǎn),左補(bǔ)零,右對(duì)齊。
  string _Dest_Id; // 21 Octet String 目的號(hào)碼。
  //   SP的服務(wù)代碼,一般4--6位,或者是前綴為服務(wù)代碼的長(zhǎng)號(hào)碼;該號(hào)碼是手機(jī)用戶(hù)短消息的被叫號(hào)碼。
  string _Service_Id; // 10 Octet String 業(yè)務(wù)標(biāo)識(shí),是數(shù)字、字母和符號(hào)的組合。
  uint _TP_pid; // 1 Unsigned Integer GSM協(xié)議類(lèi)型。詳細(xì)解釋請(qǐng)參考GSM03.40中的9.2.3.9。
  uint _TP_udhi; // 1 Unsigned Integer GSM協(xié)議類(lèi)型。詳細(xì)解釋請(qǐng)參考GSM03.40中的9.2.3.23,僅使用1位,右對(duì)齊。
  uint _Msg_Fmt; // 1 Unsigned Integer 信息格式:
  //   0:ASCII串;
  //   3:短信寫(xiě)卡操作;
  //   4:二進(jìn)制信息;
  //   8:UCS2編碼;
  //   15:含GB漢字。
  string _Src_terminal_Id; // 32 Octet String 源終端MSISDN號(hào)碼(狀態(tài)報(bào)告時(shí)填為CMPP_SUBMIT消息的目的終端號(hào)碼)。
  uint _Src_terminal_type; // 1 Unsigned Integer 源終端號(hào)碼類(lèi)型,0:真實(shí)號(hào)碼;1:偽碼。
  uint _Registered_Delivery; // 1 Unsigned Integer 是否為狀態(tài)報(bào)告:
  //   0:非狀態(tài)報(bào)告;
  //   1:狀態(tài)報(bào)告。
  uint _Msg_Length; // 1 Unsigned Integer 消息長(zhǎng)度,取值大于或等于0。
  string _Msg_Content; // Msg_length Octet String 消息內(nèi)容。
  string _LinkID; // 20 Octet String 點(diǎn)播業(yè)務(wù)使用的LinkID,非點(diǎn)播類(lèi)業(yè)務(wù)的MT流程不使用該字段。

  MessageHeader _Header;


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

  public const int FixedBodyLength = 8 // Msg_Id Unsigned Integer 信息標(biāo)識(shí)。
   //   生成算法如下:
   //   采用64位(8字節(jié))的整數(shù):
   //   (1)????????? 時(shí)間(格式為MMDDHHMMSS,即月日時(shí)分秒):bit64~bit39,其中
   //   bit64~bit61:月份的二進(jìn)制表示;
   //   bit60~bit56:日的二進(jìn)制表示;
   //   bit55~bit51:小時(shí)的二進(jìn)制表示;
   //   bit50~bit45:分的二進(jìn)制表示;
   //   bit44~bit39:秒的二進(jìn)制表示;
   //   (2)????????? 短信網(wǎng)關(guān)代碼:bit38~bit17,把短信網(wǎng)關(guān)的代碼轉(zhuǎn)換為整數(shù)填寫(xiě)到該字段中;
   //   (3)????????? 序列號(hào):bit16~bit1,順序增加,步長(zhǎng)為1,循環(huán)使用。
   //   各部分如不能填滿(mǎn),左補(bǔ)零,右對(duì)齊。
   + 21 // Dest_Id Octet String 目的號(hào)碼。
   //   SP的服務(wù)代碼,一般4--6位,或者是前綴為服務(wù)代碼的長(zhǎng)號(hào)碼;該號(hào)碼是手機(jī)用戶(hù)短消息的被叫號(hào)碼。
   + 10 // Service_Id Octet String 業(yè)務(wù)標(biāo)識(shí),是數(shù)字、字母和符號(hào)的組合。
   + 1 // TP_pid Unsigned Integer GSM協(xié)議類(lèi)型。詳細(xì)解釋請(qǐng)參考GSM03.40中的9.2.3.9。
   + 1 // TP_udhi Unsigned Integer GSM協(xié)議類(lèi)型。詳細(xì)解釋請(qǐng)參考GSM03.40中的9.2.3.23,僅使用1位,右對(duì)齊。
   + 1 // Msg_Fmt Unsigned Integer 信息格式:
   //   0:ASCII串;
   //   3:短信寫(xiě)卡操作;
   //   4:二進(jìn)制信息;
   //   8:UCS2編碼;
   //   15:含GB漢字。
   + 32 // Src_terminal_Id Octet String 源終端MSISDN號(hào)碼(狀態(tài)報(bào)告時(shí)填為CMPP_SUBMIT消息的目的終端號(hào)碼)。
   + 1 // Src_terminal_type Unsigned Integer 源終端號(hào)碼類(lèi)型,0:真實(shí)號(hào)碼;1:偽碼。
   + 1 // Registered_Delivery Unsigned Integer 是否為狀態(tài)報(bào)告:
   //   0:非狀態(tài)報(bào)告;
   //   1:狀態(tài)報(bào)告。
   + 1 // Msg_Length Unsigned Integer 消息長(zhǎng)度,取值大于或等于0。
   //Msg_length // Msg_Content Octet String 消息內(nèi)容。
   + 20; // LinkID Octet String 點(diǎn)播業(yè)務(wù)使用的LinkID,非點(diǎn)播類(lèi)業(yè)務(wù)的MT流程不使用該字段。
  public int _BodyLength;

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

   //Msg_Id 8
   i += MessageHeader.Length;
   buffer = new byte[8];
   Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length);
   Array.Reverse(buffer);
   this._Msg_Id = BitConverter.ToUInt64(buffer, 0);

   //Dest_Id 21
   i += 8;
   buffer = new byte[21];
   Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length);
   this._Dest_Id = Encoding.ASCII.GetString(buffer).Trim();

   //Service_Id 20
   i += 21;
   buffer = new byte[10];
   Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length);
   this._Service_Id = Encoding.ASCII.GetString(buffer).Trim();

   //TP_pid 1
   i += 10;
   this._TP_pid = (uint) bytes[i++];
   this._TP_udhi = (uint) bytes[i++];
   this._Msg_Fmt = (uint) bytes[i++];

   //Src_terminal_Id 32
   buffer = new byte[32];
   Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length);
   this._Src_terminal_Id = Encoding.ASCII.GetString(buffer).Trim();


   //Src_terminal_type 1
   i += 32;
   this._Src_terminal_type = (uint) bytes[i++];
   this._Registered_Delivery = (uint) bytes[i++];
   this._Msg_Length = (uint) bytes[i++];

   //Msg_Content
   buffer = new byte[this._Msg_Length];
   Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length);
   switch (this._Msg_Fmt)
   {
    case 8:
     this._Msg_Content = Encoding.BigEndianUnicode.GetString(buffer).Trim();
     break;
    case 15: //gb2312
     this._Msg_Content = Encoding.GetEncoding("gb2312").GetString(buffer).Trim();
     break;
    case 0: //ascii
    case 3: //短信寫(xiě)卡操作
    case 4: //二進(jìn)制信息
    default:
     this._Msg_Content = Encoding.ASCII.GetString(buffer).ToString();
     break;
   }


   //Linkid 20
   i += (int) this._Msg_Length;
   buffer = new byte[20];
   Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length);
   this._LinkID = Encoding.ASCII.GetString(buffer).Trim();

  }

  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: //短信寫(xiě)卡操作
    case 4: //二進(jìn)制信息
    default:
     buf = Encoding.ASCII.GetBytes(this._Msg_Content);
     break;
   }

   this._Msg_Length = (uint) buf.Length;
   this._BodyLength = FixedBodyLength + (int) this._Msg_Length;

   byte[] bytes = new byte[MessageHeader.Length + this._BodyLength];

   int i = 0;

   byte[] buffer = null;
   //header 12
   this._Header = new MessageHeader((uint) (MessageHeader.Length + this._BodyLength), CMPP_Command_Id.CMPP_DELIVER, 0);


   //Msg_Id 8
   i += MessageHeader.Length;
   buffer = new Byte[8];
   buffer = BitConverter.GetBytes(this._Msg_Id);
   Array.Reverse(buffer);
   Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length);

   //Dest_Id 21
   i += 8;
   buffer = new byte[21];
   buffer = Encoding.ASCII.GetBytes(this._Dest_Id);
   Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length);

   //Service_Id 10
   i += 21;
   buffer = new byte[10];
   buffer = Encoding.ASCII.GetBytes(this._Service_Id);
   Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length);

   //TP_pid 1
   i += 10;
   bytes[i++] = (byte) this._TP_pid;
   bytes[i++] = (byte) this._TP_udhi;
   bytes[i++] = (byte) this._Msg_Fmt;

   //Src_terminal_Id 32
   buffer = new byte[32];
   buffer = Encoding.ASCII.GetBytes(this._Src_terminal_Id);
   Buffer.BlockCopy(buffer, 0, bytes, i, buffer.Length);

   //Src_terminal_type 1
   i += 32;
   bytes[i++] = (byte) this._Src_terminal_type;
   bytes[i++] = (byte) this._Registered_Delivery;
   bytes[i++] = (byte) this._Msg_Length;

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

   //LinkID
   i += (int) this._Msg_Length;

   return bytes;
  }
 }

 class CMPP_DELIVER_RESP : CMPP_Response
 {
  private MessageHeader _Header;
  private ulong _Msg_Id;
  private uint _Result;
  public const int Bodylength = 8 + 4;

  public CMPP_DELIVER_RESP(ulong Msg_Id, uint Result)
  {
   this._Msg_Id = Msg_Id;
   this._Result = Result;
  }

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

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

   //msg_id 8
   buffer = BitConverter.GetBytes(this._Msg_Id);
   Array.Reverse(buffer);
   buffer.CopyTo(bytes, i);

   //result 4
   i += 8;
   buffer = BitConverter.GetBytes(this._Result);
   Array.Reverse(buffer);
   buffer.CopyTo(bytes, i);
   return bytes;


  }
 }


 class CMPP_Msg_Content //狀態(tài)報(bào)告
 {
  public const int BodyLength = 8 + 7 + 10 + 10 + 32 + 4;
  private uint _Msg_Id; // 8 Unsigned Integer 信息標(biāo)識(shí)。SP提交短信(CMPP_SUBMIT)操作時(shí),與SP相連的ISMG產(chǎn)生的Msg_Id。
  private string _Stat; // 7 Octet String 發(fā)送短信的應(yīng)答結(jié)果,含義詳見(jiàn)表一。SP根據(jù)該字段確定CMPP_SUBMIT消息的處理狀態(tài)。
  private string _Submit_time; // 10 Octet String YYMMDDHHMM(YY為年的后兩位00-99,MM:01-12,DD:01-31,HH:00-23,MM:00-59)。
  private string _Done_time; // 10 Octet String YYMMDDHHMM。
  public CMPP_Msg_Content(byte[] bytes)
  {
   if (bytes.Length == BodyLength)
   {
    int i = 0;
    //_Msg_Id 8
    byte[] buffer = new byte[8];
    Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length);
    Array.Reverse(buffer);
    this._Msg_Id = BitConverter.ToUInt32(buffer, 0);

    //_Stat 7
    i += 8;
    buffer = new byte[7];
    Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length);
    this._Stat = Encoding.ASCII.GetString(buffer);

    //_Submit_time 10
    i += 7;
    buffer = new byte[10];
    Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length);
    this._Submit_time = Encoding.ASCII.GetString(buffer);

    //_Done_time 10
    i += 10;
    buffer = new byte[10];
    Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length);
    this._Submit_time = Encoding.ASCII.GetString(buffer);

    //Dest_terminal_Id 32
    i += 10;
    buffer = new byte[32];
    Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length);
    this._Dest_terminal_Id = Encoding.ASCII.GetString(buffer);

    //SMSC_sequence 4
    i += 32;
    buffer = new byte[4];
    Buffer.BlockCopy(bytes, i, buffer, 0, buffer.Length);
    Array.Reverse(buffer);
    this._SMSC_sequence = BitConverter.ToUInt32(buffer,0);
   }
  }

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

  public string Stat
  {
   get
   {
    return this._Stat;
   }
   set
   {
    this._Stat = value;
   }
  }

  public string Submit_time
  {
   get
   {
    return this._Submit_time;
   }
   set
   {
    this._Submit_time = value;
   }
  }

  public string Done_time
  {
   get
   {
    return this._Done_time;
   }
   set
   {
    this._Done_time = value;
   }
  }

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

  public uint SMSC_sequence
  {
   get
   {
    return this._SMSC_sequence;
   }
   set
   {
    this._SMSC_sequence = value;
   }
  }

  private string _Dest_terminal_Id; // 32 Octet String 目的終端MSISDN號(hào)碼(SP發(fā)送CMPP_SUBMIT消息的目標(biāo)終端)。
  private uint _SMSC_sequence; // 4 Unsigned Integer 取自SMSC發(fā)送狀態(tài)報(bào)告的消息體中的消息標(biāo)識(shí)。
 }
 class CMPP_QUERY : CMPP_Request
 {
  MessageHeader _Header;
  
  string _Time;  // 8 Octet String 時(shí)間YYYYMMDD(精確至日)。
  uint _Query_Type; // 1 Unsigned Integer 查詢(xún)類(lèi)別:
  //   0:總數(shù)查詢(xún);
  //   1:按業(yè)務(wù)類(lèi)型查詢(xún)。
  string _Query_Code; // 10 Octet String 查詢(xún)碼。
  //   當(dāng)Query_Type為0時(shí),此項(xiàng)無(wú)效;當(dāng)Query_Type為1時(shí),此項(xiàng)填寫(xiě)業(yè)務(wù)類(lèi)型Service_Id.。
  string _Reserve; // 8 Octet String 保留。

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

  public string Time
  {
   get
   {
    return this._Time;
   }
  }

  public uint Query_Type
  {
   get
   {
    return this._Query_Type;
   }
  }

  public string Query_Code
  {
   get
   {
    return this._Query_Code;
   }
  }

  public string Reserve
  {
   get
   {
    return this._Reserve;
   }
  }
  public const int BodyLength = 8 + 1 + 10 + 8;
  public CMPP_QUERY(System.DateTime Time,uint Query_Type,string Query_Code,string Reserve)
  {
   this._Time = Util.Get_YYYYMMDD_String(Time);
   this._Query_Type = Query_Type;
   this._Query_Code = Query_Code;
   this._Reserve = Reserve;
  }
  public byte[] ToBytes()
  {
   int i = 0;
   byte[] bytes = new byte[MessageHeader.Length + BodyLength];
   //header
   this._Header = new MessageHeader((uint) (MessageHeader.Length + BodyLength), CMPP_Command_Id.CMPP_QUERY, 0);
   byte[] buffer = new byte[MessageHeader.Length];
   buffer = this._Header.ToBytes();
   buffer.CopyTo(bytes,0);

   //Time 8
   i += MessageHeader.Length;
   buffer = new byte[10];
   buffer = Encoding.ASCII.GetBytes(this._Time);
   buffer.CopyTo(bytes,i);
   
   //Query_Type 1
   i += 8;
   bytes[i++] = (byte) this._Query_Type;

   //Query_Code 10
   buffer = new byte[10];
   buffer = Encoding.ASCII.GetBytes(this._Query_Code);
   buffer.CopyTo(bytes,i);

   //Reserve 8
   i += 10;
   buffer = new byte[8];
   buffer = Encoding.ASCII.GetBytes(this._Reserve);
   buffer.CopyTo(bytes,i);
   
   return bytes;
  }
 }

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

  public string Time
  {
   get
   {
    return this._Time;
   }
  }

  public uint Query_Type
  {
   get
   {
    return this._Query_Type;
   }
  }

  public string Query_Code
  {
   get
   {
    return this._Query_Code;
   }
  }

  public uint Mt_TlMsg
  {
   get
   {
    return this._MT_TLMsg;
   }
  }

  public uint Mt_Tlusr
  {
   get
   {
    return this._MT_Tlusr;
   }
  }

  public uint Mt_Scs
  {
   get
   {
    return this._MT_Scs;
   }
  }

  public uint Mt_Wt
  {
   get
   {
    return this._MT_WT;
   }
  }

  public uint Mt_Fl
  {
   get
   {
    return this._MT_FL;
   }
  }

  public uint Mo_Scs
  {
   get
   {
    return this._MO_Scs;
   }
  }

  public uint Mo_Wt
  {
   get
   {
    return this._MO_WT;
   }
  }

  public uint Mo_Fl
  {
   get
   {
    return this._MO_FL;
   }
  }

  MessageHeader _Header;
  string _Time;  // 8 Octet String 時(shí)間(精確至日)。
  uint _Query_Type; // 1 Unsigned Integer 查詢(xún)類(lèi)別:
       //   0:總數(shù)查詢(xún);
       //   1:按業(yè)務(wù)類(lèi)型查詢(xún)。
  string _Query_Code; // 10 Octet String 查詢(xún)碼。
  uint _MT_TLMsg;  // 4 Unsigned Integer 從SP接收信息總數(shù)。
  uint _MT_Tlusr;  // 4 Unsigned Integer 從SP接收用戶(hù)總數(shù)。
  uint _MT_Scs;  // 4 Unsigned Integer 成功轉(zhuǎn)發(fā)數(shù)量。
  uint _MT_WT;  // 4 Unsigned Integer 待轉(zhuǎn)發(fā)數(shù)量。
  uint _MT_FL;  // 4 Unsigned Integer 轉(zhuǎn)發(fā)失敗數(shù)量。
  uint _MO_Scs;  // 4 Unsigned Integer 向SP成功送達(dá)數(shù)量。
  uint _MO_WT;  // 4 Unsigned Integer 向SP待送達(dá)數(shù)量。
  uint _MO_FL;  // 4 Unsigned Integer 向SP送達(dá)失敗數(shù)量。


  public const int BodyLength = 8  // Octet String 時(shí)間(精確至日)。
         + 1  // Unsigned Integer 查詢(xún)類(lèi)別:
           //  0:總數(shù)查詢(xún);
           //  1:按業(yè)務(wù)類(lèi)型查詢(xún)。
         + 10 // Octet String 查詢(xún)碼。
         + 4  // Unsigned Integer 從SP接收信息總數(shù)。
         + 4  // Unsigned Integer 從SP接收用戶(hù)總數(shù)。
         + 4  // Unsigned Integer 成功轉(zhuǎn)發(fā)數(shù)量。
         + 4  // Unsigned Integer 待轉(zhuǎn)發(fā)數(shù)量。
         + 4  // Unsigned Integer 轉(zhuǎn)發(fā)失敗數(shù)量。
         + 4  // Unsigned Integer 向SP成功送達(dá)數(shù)量。
         + 4  // Unsigned Integer 向SP待送達(dá)數(shù)量。
         + 4; // Unsigned Integer 向SP送達(dá)失敗數(shù)量。


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

   //Time 8
   i += MessageHeader.Length;
   buffer = new byte[8];
   Buffer.BlockCopy(bytes,i,buffer,0,buffer.Length);
   this._Time = Encoding.ASCII.GetString(buffer);

   //Query_Type 1
   i += 8;
   this._Query_Type = (uint) bytes[i++];

   //Query_Code 10
   buffer = new byte[10];
   Buffer.BlockCopy(bytes,i,buffer,0,buffer.Length);
   this._Query_Code = Encoding.ASCII.GetString(buffer);

   //MT_TLMsg 4
   i += 10;
   buffer = new byte[4];
   Buffer.BlockCopy(bytes,i,buffer,0,buffer.Length);
   Array.Reverse(buffer);
   this._MT_TLMsg = BitConverter.ToUInt32(buffer,0);

   //MT_Tlusr 4
   i += 4;
   buffer = new byte[4];
   Buffer.BlockCopy(bytes,i,buffer,0,buffer.Length);
   Array.Reverse(buffer);
   this._MT_Tlusr = BitConverter.ToUInt32(buffer,0);

   //MT_Scs 4
   i += 4;
   buffer = new byte[4];
   Buffer.BlockCopy(bytes,i,buffer,0,buffer.Length);
   Array.Reverse(buffer);
   this._MT_Scs = BitConverter.ToUInt32(buffer,0);

   //MT_WT 4
   i += 4;
   buffer = new byte[4];
   Buffer.BlockCopy(bytes,i,buffer,0,buffer.Length);
   Array.Reverse(buffer);
   this._MT_WT = BitConverter.ToUInt32(buffer,0);

   //MT_FL 4
   i += 4;
   buffer = new byte[4];
   Buffer.BlockCopy(bytes,i,buffer,0,buffer.Length);
   Array.Reverse(buffer);
   this._MT_FL = BitConverter.ToUInt32(buffer,0);

   //MO_Scs 4
   i += 4;
   buffer = new byte[4];
   Buffer.BlockCopy(bytes,i,buffer,0,buffer.Length);
   Array.Reverse(buffer);
   this._MO_Scs = BitConverter.ToUInt32(buffer,0);

   //MO_WT 4
   i += 4;
   buffer = new byte[4];
   Buffer.BlockCopy(bytes,i,buffer,0,buffer.Length);
   Array.Reverse(buffer);
   this._MO_WT = BitConverter.ToUInt32(buffer,0);

   //MO_FL 4
   i += 4;
   buffer = new byte[4];
   Buffer.BlockCopy(bytes,i,buffer,0,buffer.Length);
   Array.Reverse(buffer);
   this._MO_FL = BitConverter.ToUInt32(buffer,0);
  }
 }


 class CMPP_ACTIVE_TEST
 {
  MessageHeader _Header;

  public MessageHeader Header
  {
   get
   {
    return this._Header;
   }
  }
  public CMPP_ACTIVE_TEST()
  {
   this._Header = new MessageHeader(MessageHeader.Length,CMPP_Command_Id.CMPP_ACTIVE_TEST,0);
  }
  public byte[] ToBytes()
  {
   return this._Header.ToBytes();
  }
 }
 class CMPP_ACTIVE_TEST_RESP
 {
  MessageHeader _Header;
  byte _Reserved;

  public byte Reserved
  {
   get
   {
    return this._Reserved;
   }   
  }
  public MessageHeader Header
  {
   get
   {
    return this._Header;
   }
  }
  public CMPP_ACTIVE_TEST_RESP(byte[] bytes)
  {
   int i = 0;
   //header
   byte[] buffer = new byte[MessageHeader.Length];
   Buffer.BlockCopy(bytes,i,buffer,0,buffer.Length);
   this._Header = new MessageHeader(buffer);
   
   //Reserved 1
   i += MessageHeader.Length;
   this._Reserved = bytes[i];
  }
  public byte[] ToBytes()
  {
   return this._Header.ToBytes();
  }  
 }

}

//測(cè)試程序

namespace Test
{
 using System;
 using System.Text;
 using System.Net.Sockets;
 using System.Threading;
 using Microshaoft.CMPP.Messages;

 public class ConsoleApplication
 {
  static void Main()
  {
   Console.WriteLine("請(qǐng)先運(yùn)行并啟動(dòng):\n《中國(guó)移動(dòng)通信 CMPP v3.0 短消息網(wǎng)關(guān)模擬器 v1.10》進(jìn)行測(cè)試:"
    + "\n下載于: 《北京風(fēng)起水流軟件工作室》"
    + "\nhttp://www.zealware.com/download/cmpp3pro.rar\n");
   Console.WriteLine("按任意鍵\n測(cè)試: SP 向 ISMG 提交短信 (CMPP_SUBMIT) 操作");
   Console.ReadLine();
   Console.WriteLine("請(qǐng)注意觀(guān)察《中國(guó)移動(dòng)通信 CMPP v3.0 短消息網(wǎng)關(guān)模擬器》系統(tǒng)狀態(tài)!");
   Submit(); //SP -> ISMG 群發(fā)短信
   Console.WriteLine("\n==============================================================");
   Console.WriteLine("按任意鍵\n測(cè)試: SP 向 ISMG 查詢(xún)發(fā)送短信狀態(tài) (CMPP_QUERY) 操作");
   Console.ReadLine();
   Console.WriteLine("請(qǐng)注意觀(guān)察《中國(guó)移動(dòng)通信 CMPP v3.0 短消息網(wǎng)關(guān)模擬器》系統(tǒng)狀態(tài)!");
   Query(); //SP -> ISMG 查詢(xún)短信
   Console.WriteLine("\n==============================================================");
   Console.WriteLine("\n按任意鍵\n測(cè)試: ISMG 向 SP 送交短信 (CMPP_DELIVER) 操作");
   Console.ReadLine(); //ISMG -> SP
   Console.WriteLine("請(qǐng)?jiān)凇吨袊?guó)移動(dòng)通信 CMPP v3.0 短消息網(wǎng)關(guān)模擬器》下發(fā)消息!");
   Console.WriteLine("該模擬器不能自動(dòng)生成\"狀態(tài)報(bào)告\"!\n請(qǐng)?jiān)谠撃M器中下發(fā)消息中自行鍵入下面短信內(nèi)容后,并將 Registered_Delivery = 1 ,再發(fā)送:");
   Console.WriteLine("00000001DELIVRD031213505003121350501391xxx11381391xxx11381391xx11380001");

   //訂閱短信到達(dá)事件 ISMG -> SP
   CMPP_Deliver += new CMPP_DeliverEventHandler(ConsoleApplication_CMPP_Deliver);

   new Thread(new ThreadStart(DoWait)).Start();
   
   //該模擬器不能自動(dòng)生成狀態(tài)報(bào)告再下發(fā)!請(qǐng)自行鍵入下面短信內(nèi)容后,發(fā)送
   //狀態(tài)報(bào)告短信: 00000001DELIVRD031213505003121350501391xxx11381391xxx11381391xx11380001
   Deliver(); //ISMG -> SP 接收短信
   Console.ReadLine();
  }

  //退出程序(死循環(huán))標(biāo)志
  static bool B = false;

  static void DoWait()
  {
   while (Console.ReadLine().ToLower() != "q")
   {
    Console.WriteLine("press 'q' to exit this programe!");
   }
   B = true;
   Console.WriteLine("bye!");
  }

  static void Query()
  {
   NetworkStream S;
   if (CMPP_CONNECT_RESP(out S))
   {
    if (S.CanWrite)
    {
     byte[] buffer = new CMPP_QUERY(System.DateTime.Parse("2005-1-1"),1,"001","").ToBytes();
     S.Write(buffer,0,buffer.Length); 
     if (S.CanRead)
     {
      buffer =  ResponseAsBytes(S, MessageHeader.Length + CMPP_QUERY_RESP.BodyLength, 16);
      CMPP_QUERY_RESP query_resp = new CMPP_QUERY_RESP(buffer);
      PrintHeader(query_resp.Header);
      Console.WriteLine("{0},{1}",query_resp.Time,query_resp.Query_Code);
     }
    }
   }
   S.Close();
   S = null;
  }
  
  //聲明短信到達(dá)處理事件
  public delegate void CMPP_DeliverEventHandler(CMPP_DELIVER cmpp_deliver);
  public static event CMPP_DeliverEventHandler CMPP_Deliver;

  static void Deliver()
  {
   NetworkStream S;
   if (CMPP_CONNECT_RESP(out S))
   {
    int s = 10; //buffer size
    byte[] bytes = new byte[400];
    while (!B)
    {
     if (S.CanRead)
     {
      if (S.DataAvailable)
      {

       byte[] buffer = null;
       buffer = ResponseAsBytes(S, bytes.Length, s);

       if (buffer.Length > 0)
       {
        CMPP_DELIVER deliver = new CMPP_DELIVER(buffer);
        PrintHeader(deliver.Header);
        if (CMPP_Deliver != null)
        {
         CMPP_Deliver(deliver);
        }
        if (S.CanWrite)
        {
         CMPP_DELIVER_RESP deliver_resp = new CMPP_DELIVER_RESP(deliver.Msg_Id, 0);
         buffer = deliver_resp.ToBytes();
         S.Write(buffer, 0, buffer.Length);
        }

       }
       
      }
     }
    }
    MessageHeader terminate = new MessageHeader(MessageHeader.Length, CMPP_Command_Id.CMPP_TERMINATE, 1);
    if (S.CanWrite)
    {
     S.Write(terminate.ToBytes(), 0, MessageHeader.Length);
    }

    if (S.CanRead)
    {
     bytes = ResponseAsBytes(S, MessageHeader.Length, s);
     MessageHeader terminate_resp = new MessageHeader(bytes);
     PrintHeader(terminate_resp);
    }
    S.Close();
    S = null;

   }
  }

  static bool CMPP_CONNECT_RESP(out NetworkStream Stream)
  {
   bool b = false;
   TcpClient tc = new TcpClient();
   tc.Connect("127.0.0.1", 7890);
   string UserID = "901234";
   string Password = "1234";
   CMPP_CONNECT connect = new CMPP_CONNECT(UserID, Password, DateTime.Now, 1);
   PrintHeader(connect.Header);

   byte[] bytes = connect.ToBytes();
   Stream = tc.GetStream();
   if (Stream.CanWrite)
   {
    Stream.Write(bytes, 0, bytes.Length);
   }
   if (Stream.CanRead)
   {
    int s = 10; //buffer size
    bytes = ResponseAsBytes(Stream, MessageHeader.Length + CMPP_CONNECT_RESP.BodyLength, s);
    CMPP_CONNECT_RESP connect_resp = new CMPP_CONNECT_RESP(bytes);
    PrintHeader(connect_resp.Header);
    if (connect_resp.Header.Command_Id == CMPP_Command_Id.CMPP_CONNECT_RESP)
    {
     b = connect_resp.Status == 0;
    }
   }
   return b;
  }

  static void Submit()
  {
   TcpClient tc = new TcpClient();
   tc.Connect("127.0.0.1", 7890);
   string UserID = "901234";
   string Password = "1234";
   CMPP_CONNECT connect = new CMPP_CONNECT(UserID, Password, DateTime.Now, 1);
   PrintHeader(connect.Header);

   byte[] bytes = connect.ToBytes();
   NetworkStream ns = tc.GetStream();
   if (ns.CanWrite)
   {
    ns.Write(bytes, 0, bytes.Length);
   }
   if (ns.CanRead)
   {
    int s = 10; //buffer size
    bytes = ResponseAsBytes(ns, MessageHeader.Length + CMPP_CONNECT_RESP.BodyLength, s);
    CMPP_CONNECT_RESP connect_resp = new CMPP_CONNECT_RESP(bytes);
    PrintHeader(connect_resp.Header);
    if (connect_resp.Header.Command_Id == CMPP_Command_Id.CMPP_CONNECT_RESP)
    {
     if (connect_resp.Status == 0)
     {
      CMPP_SUBMIT submit = new CMPP_SUBMIT();
      //submit.Msg_Id = 0;        //      uint _Msg_Id;      // 8 Unsigned Integer 信息標(biāo)識(shí)。
      submit.Pk_total = 1; //      uint _Pk_total;      // 1 Unsigned Integer 相同Msg_Id的信息總條數(shù),從1開(kāi)始。
      submit.Pk_number = 0; //      uint _Pk_number;     // 1 Unsigned Integer 相同Msg_Id的信息序號(hào),從1開(kāi)始。
      submit.Registered_Delivery = 1; //      uint _Registered_Delivery;   // 1 Unsigned Integer 是否要求返回狀態(tài)確認(rèn)報(bào)告:
      //      //   0:不需要;
      //      //   1:需要。
      submit.Msg_level = 1; //      uint _Msg_level;     // 1 Unsigned Integer 信息級(jí)別。
      submit.Service_Id = "abcdefghij"; //      string _Service_Id;     // 10 Octet String 業(yè)務(wù)標(biāo)識(shí),是數(shù)字、字母和符號(hào)的組合。
      submit.Fee_UserType = 3; //      uint _Fee_UserType;     // 1 Unsigned Integer 計(jì)費(fèi)用戶(hù)類(lèi)型字段:
      //      //   0:對(duì)目的終端MSISDN計(jì)費(fèi);
      //      //   1:對(duì)源終端MSISDN計(jì)費(fèi);
      //      //   2:對(duì)SP計(jì)費(fèi);
      //      //   3:表示本字段無(wú)效,對(duì)誰(shuí)計(jì)費(fèi)參見(jiàn)Fee_terminal_Id字段。
      submit.Fee_terminal_Id = "1391xxx1138"; //      string _Fee_terminal_Id;   // 32 Octet String 被計(jì)費(fèi)用戶(hù)的號(hào)碼,當(dāng)Fee_UserType為3時(shí)該值有效,當(dāng)Fee_UserType為0、1、2時(shí)該值無(wú)意義。
      submit.Fee_terminal_type = 0; //      uint _Fee_terminal_type;   // 1 Unsigned Integer 被計(jì)費(fèi)用戶(hù)的號(hào)碼類(lèi)型,0:真實(shí)號(hào)碼;1:偽碼。

      submit.Tp_pId = 0; //      uint _TP_pId;      // 1 Unsigned Integer GSM協(xié)議類(lèi)型。詳細(xì)是解釋請(qǐng)參考GSM03.40中的9.2.3.9。
      submit.Tp_udhi = 0; //      uint _TP_udhi;      // 1 Unsigned Integer GSM協(xié)議類(lèi)型。詳細(xì)是解釋請(qǐng)參考GSM03.40中的9.2.3.23,僅使用1位,右對(duì)齊。
      submit.Msg_Fmt = 15; //      uint _Msg_Fmt;      // 1 Unsigned Integer 信息格式:
      //      //   0:ASCII串;
      //      //   3:短信寫(xiě)卡操作;
      //      //   4:二進(jìn)制信息;
      //      //   8:UCS2編碼;
      //      //   15:含GB漢字。。。。。。
      submit.Msg_src = UserID; //      string _Msg_src;     // 6 Octet String 信息內(nèi)容來(lái)源(SP_Id)。
      submit.FeeType = "02"; //      string _FeeType;     // 2 Octet String 資費(fèi)類(lèi)別:
      //      //   01:對(duì)"計(jì)費(fèi)用戶(hù)號(hào)碼"免費(fèi);
      //      //   02:對(duì)"計(jì)費(fèi)用戶(hù)號(hào)碼"按條計(jì)信息費(fèi);
      //      //   03:對(duì)"計(jì)費(fèi)用戶(hù)號(hào)碼"按包月收取信息費(fèi)。
      submit.FeeCode = "100"; //      string _FeeCode;     // 6 Octet String 資費(fèi)代碼(以分為單位)。
      //Why not 17?
      submit.ValId_Time = Util.Get_MMDDHHMMSS_String(DateTime.Now.AddHours(2)) + "032+"; //      string _ValId_Time;     // 17 Octet String 存活有效期,格式遵循SMPP3.3協(xié)議。
      submit.At_Time = Util.Get_MMDDHHMMSS_String(DateTime.Now) + "032+"; //      string _At_Time;     // 17 Octet String 定時(shí)發(fā)送時(shí)間,格式遵循SMPP3.3協(xié)議。
      //spnum
      submit.Src_Id = ""; //      string _Src_Id;      // 21 Octet String 源號(hào)碼。SP的服務(wù)代碼或前綴為服務(wù)代碼的長(zhǎng)號(hào)碼, 網(wǎng)關(guān)將該號(hào)碼完整的填到SMPP協(xié)議Submit_SM消息相應(yīng)的source_addr字段,該號(hào)碼最終在用戶(hù)手機(jī)上顯示為短消息的主叫號(hào)碼。

      submit.Dest_terminal_Id = new string[] {"1391xxx1138", "1391xxx1137"}; //      string[] _Dest_terminal_Id;   // 32*DestUsr_tl Octet String 接收短信的MSISDN號(hào)碼。
      submit.DestUsr_tl = (uint) submit.Dest_terminal_Id.Length; //      uint _DestUsr_tl;     // 1 Unsigned Integer 接收信息的用戶(hù)數(shù)量(小于100個(gè)用戶(hù))。

      //
      //
      submit.Dest_terminal_type = 0; //      uint _Dest_terminal_type;   // 1 Unsigned Integer 接收短信的用戶(hù)的號(hào)碼類(lèi)型,0:真實(shí)號(hào)碼;1:偽碼。
      submit.Msg_Fmt = 15; //      uint _Msg_Length;     // 1 Unsigned Integer 信息長(zhǎng)度(Msg_Fmt值為0時(shí):<160個(gè)字節(jié);其它<=140個(gè)字節(jié)),取值大于或等于0。
      submit.Msg_Content = "大家好!這是一個(gè)短信群發(fā)測(cè)試!"; //      string _Msg_Content;    // Msg_length Octet String 信息內(nèi)容。
      submit.LinkId = ""; //      string _LinkID;      // 20 Octet String 點(diǎn)播業(yè)務(wù)使用的LinkID,非點(diǎn)播類(lèi)業(yè)務(wù)的MT流程不使用該字段。

      bytes = submit.ToBytes();
      if (ns.CanWrite)
      {
       ns.Write(bytes, 0, bytes.Length);
      }
      if (ns.CanRead)
      {
       bytes = ResponseAsBytes(ns, MessageHeader.Length + CMPP_SUBMIT_RESP.BodyLength, s);
       CMPP_SUBMIT_RESP submit_resp = new CMPP_SUBMIT_RESP(bytes);
       Console.WriteLine(submit_resp.Msg_Id);
       Console.WriteLine(submit_resp.Result);
       PrintHeader(submit_resp.Header);

       MessageHeader terminate = new MessageHeader(MessageHeader.Length, CMPP_Command_Id.CMPP_TERMINATE, 1);
       if (ns.CanWrite)
       {
        ns.Write(terminate.ToBytes(), 0, MessageHeader.Length);
       }
       if (ns.CanRead)
       {
        bytes = ResponseAsBytes(ns, MessageHeader.Length, s);
        MessageHeader terminate_resp = new MessageHeader(bytes);
        PrintHeader(terminate_resp);
       }
       ns.Close();
       ns = null;
      }
     }
    }
   }
  }

  private static byte[] ResponseAsBytes(NetworkStream Stream, int Length, int BufferSize)
  {
   int l;
   byte[] bytes = new byte[Length];
   l = 0;

   do
   {
    byte[] buffer = new byte[BufferSize];
    int r = Stream.Read(buffer, 0, buffer.Length);
    if (r > 0)
    {
     Buffer.BlockCopy(buffer, 0, bytes, l, r);
     l += r;
    }
   } while (Stream.DataAvailable);

   byte[] Bytes = new byte[l];
   Buffer.BlockCopy(bytes, 0, Bytes, 0, Bytes.Length);
   return Bytes;
  }

  public static void PrintHeader(MessageHeader Header)
  {
   Console.WriteLine(Header.Total_Length);
   Console.WriteLine(Header.Command_Id);
   Console.WriteLine(Header.Sequence_Id);
  }

  //短信到達(dá)事件
  private static void ConsoleApplication_CMPP_Deliver(CMPP_DELIVER deliver)
  {
   PrintHeader(deliver.Header);
   string s = "";
   if (deliver.Registered_Delivery == 0) //普通短信
   {
    s = String.Format("普通短信: {0}\n{1}",deliver.Src_terminal_Id, deliver.Msg_Content);
   }
   else
    //該模擬器不能自動(dòng)生成狀態(tài)報(bào)告再下發(fā)!請(qǐng)自行鍵入下面短信內(nèi)容后,發(fā)送
    //狀態(tài)報(bào)告短信: 00000001DELIVRD031213505003121350501391xxx11381391xxx11381391xx11380001
   {
    CMPP_Msg_Content x = new CMPP_Msg_Content(Encoding.ASCII.GetBytes(deliver.Msg_Content));
    s = String.Format("狀態(tài)報(bào)告: {0}\n{1}",x.Stat, x.Dest_terminal_Id);
   }
   System.Console.WriteLine(s);

  }
 }

}

關(guān)鍵詞:C#