中國移動簡訊網關CMPP3.0 C#原始碼:資料包定義

來源:互聯網
上載者:User

關於聯合
CMPP定義的各種資料包採用C語言中的聯合(Union)來處理是最有效率的,因為接收和發送的是一個位元組數組,使用聯合可以方便地在位元組數組和資料包結構之間轉換。C#本身並不支援聯合,但可以使用P/Invoke(平台封送調用)機制實作類別似於聯合的結構。
在定義CMPP資料包時,我為每個資料包結構定義了Init函數(用於將位元組數群組轉換為資料包結構)和GetBuffer函數(用於將資料包結構轉換為位元組數組),主要是因為當時對P/Invoke機制不太熟悉。
使用Init和GetBuffer函數的結果是效率要比使用聯合低很多,不過壓力測試的時候系統資料表現還是相當穩定的。有興趣的朋友可以試試用聯合實現CMPP的資料包。

using System;
using System.Runtime.InteropServices;

namespace Tiray.SMS
{
 public struct DATA_PACKAGE
 {
  public UInt32 Command;
  public UInt32 SequenceID;//流水號
  public object Data;//資料
  public DateTime SendTime; //資料包發送時間
  public int SendCount;//發送次數
  public int Status;//資料包狀態 0--空,1--待發送,2--已發送
 }
 
 #region Enums
 public enum SMS_STATE
 {
  SP_CONNECT,ACTIVE_TEST,ACTIVE_TEST_RESPONSE,SUBMIT,SUBMIT_RESPONSE,DELIVER,DELIVER_RESPONSE,REPORT,SP_DISCONNECT,
  SP_CONNECT_ERROR,ACTIVE_TEST_ERROR,ACTIVE_TEST_RESPONSE_ERROR,SUBMIT_ERROR,SUBMIT_RESPONSE_ERROR,DELIVER_ERROR,DELIVER_RESPONSE_ERROR,SP_DISCONNECT_ERROR,UNKNOW_ERROR

 }

 public enum CODING
 {
  ASCII=0,BINARY=4,UCS2=8,GBK=15
 }
 #endregion

 #region CMPP30 Data Packages
 [ StructLayout( LayoutKind.Sequential, Pack=1,CharSet=CharSet.Ansi )]
 public struct CMPP_HEAD
 {
  public UInt32   TotalLength;
  public UInt32   CommandID;
  public UInt32   SequenceID;
  public Byte[] GetBuffer()
  {
   Byte[] buffer=new Byte[Marshal.SizeOf(this)];//12;
   Byte[] temp=null;
   temp=BitConverter.GetBytes(TotalLength);
   buffer[3]=temp[0];
   buffer[2]=temp[1];
   buffer[1]=temp[2];
   buffer[0]=temp[3];
   temp=BitConverter.GetBytes(CommandID);
   buffer[7]=temp[0];
   buffer[6]=temp[1];
   buffer[5]=temp[2];
   buffer[4]=temp[3];
   temp=BitConverter.GetBytes(SequenceID);
   buffer[11]=temp[0];
   buffer[10]=temp[1];
   buffer[9]=temp[2];
   buffer[8]=temp[3];
   return buffer;
  }
 }

 [ StructLayout( LayoutKind.Sequential, Pack=1,CharSet=CharSet.Ansi )]
 public struct CMPP_CONNECT
 {
  public CMPP_HEAD Head;
  
  [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=6)]
  public string SourceAddress;

  [ MarshalAs( UnmanagedType.ByValArray, SizeConst=16)]
  public Byte[] AuthenticatorSource;
  public Byte Version;
  public UInt32 TimeStamp;
  
  public Byte[] GetBuffer()
  {
   Byte[] temp=null;
   int iPos=0;
   Head.TotalLength=39;
   Byte[] buffer=new Byte[39];
   
   Byte[] HeadBuffer=this.Head.GetBuffer();
   Array.Copy(HeadBuffer,0,buffer,0,HeadBuffer.Length);
   iPos=iPos+HeadBuffer.Length;
   
   temp=Utility.Encode(SourceAddress,CODING.ASCII);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+6;
   
   Array.Copy(AuthenticatorSource,0,buffer,iPos,AuthenticatorSource.Length);
   iPos=iPos+AuthenticatorSource.Length;
   
   buffer[iPos]=Version;
   iPos++;
   
   //temp=BitConverter.GetBytes(TimeStamp);
   temp=Utility.IntToNetBytes(TimeStamp);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+temp.Length;

   return buffer;
  }

 }
 [ StructLayout( LayoutKind.Sequential, Pack=1,CharSet=CharSet.Ansi )]
 public struct CMPP_CONNECT_RESP
 {
  public CMPP_HEAD Head;
  public UInt32 Status;
  [ MarshalAs( UnmanagedType.ByValArray, SizeConst=16)]
  public Byte[] AuthenticatorISMG;
  public Byte Version;

 }
 [ StructLayout( LayoutKind.Sequential, Pack=1,CharSet=CharSet.Ansi )]
 public struct CMPP_SUBMIT
 {
  public CMPP_HEAD Head;
  public UInt64 Msg_ID;
  public Byte Pk_Total;
  public Byte Pk_Number;
  public Byte Registered_Delivery;
  public Byte Msg_Level;
  [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=10)]
  public string Service_Id;
  public Byte Fee_UserType;
  [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=32)]
  public string Fee_Terminal_Id;
  public Byte Fee_Terminal_Type;
  public Byte TP_Pid;
  public Byte TP_Udhi;
  public Byte Msg_Fmt;
  [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=6)]
  public string Msg_Src;
  [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=2)]
  public string FeeType;
  [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=6)]
  public string FeeCode;
  [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=17)]
  public string Valid_Time; 
  [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=17)]
  public string At_Time; 
  [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=21)]
  public string Src_Id;
  public Byte DestUsr_Tl;
  public string[] Dest_Terminal_ID;
  public Byte Dest_Terminal_Type;
  public Byte Msg_Length;
  public string Msg_Content;
  [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=20)]
  public String LinkID;

  public Byte[] GetBuffer()
  {
   
   int iPos=0;
   Msg_Length=(Byte)Utility.CountLength(Msg_Content.ToString(),(CODING)Msg_Fmt);
   Head.TotalLength=(UInt32)(163+32*DestUsr_Tl+Msg_Length);
   Byte[] buffer=new Byte[Head.TotalLength];
   Byte[] temp=null;
   
   Byte[] HeadBuffer=this.Head.GetBuffer();
   Array.Copy(HeadBuffer,0,buffer,0,HeadBuffer.Length);
   iPos=HeadBuffer.Length;
   
   temp=Utility.IntToNetBytes(Msg_ID);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+temp.Length;

   buffer[iPos]=Pk_Total;
   iPos++;

   buffer[iPos]=Pk_Number;
   iPos++;

   buffer[iPos]=Registered_Delivery;
   iPos++;

   buffer[iPos]=Msg_Level;
   iPos++;

   temp=Utility.Encode(Service_Id,CODING.ASCII);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+10;

   buffer[iPos]=Fee_UserType;
   iPos++;

   temp=Utility.Encode(Fee_Terminal_Id,CODING.ASCII);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+32;

   buffer[iPos]=Fee_Terminal_Type;
   iPos++;

   buffer[iPos]=TP_Pid;
   iPos++;
   
   buffer[iPos]=TP_Udhi;
   iPos++;

   buffer[iPos]=Msg_Fmt;
   iPos++;

   temp=Utility.Encode(Msg_Src,CODING.ASCII);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+6;

   temp=Utility.Encode(FeeType,CODING.ASCII);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+2;

   temp=Utility.Encode(FeeCode,CODING.ASCII);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+6;

   temp=Utility.Encode(Valid_Time,CODING.ASCII);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+17;

   temp=Utility.Encode(At_Time,CODING.ASCII);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+17;
   
   temp=Utility.Encode(Src_Id,CODING.ASCII);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+21;

   buffer[iPos]=DestUsr_Tl;
   iPos++;
   
   for(int i=0;i<DestUsr_Tl;i++)
   {
    temp=Utility.Encode(Dest_Terminal_ID[i],CODING.ASCII);
    Array.Copy(temp,0,buffer,iPos,temp.Length);
    iPos=iPos+32;
   }

   buffer[iPos]=Dest_Terminal_Type;
   iPos++;

   buffer[iPos]=Msg_Length;
   iPos++;

   temp=Utility.Encode(Msg_Content,(CODING)Msg_Fmt);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+temp.Length;

   temp=Utility.Encode(LinkID,CODING.ASCII);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+temp.Length;

   return buffer;

  }
 }

 [ StructLayout( LayoutKind.Sequential, Pack=1,CharSet=CharSet.Ansi )]
 public struct CMPP_SUBMIT_RESP
 {
  public CMPP_HEAD Head;
  public UInt64 Msg_ID;
  public UInt32 Result;

 }

 [ StructLayout( LayoutKind.Sequential, Pack=1,CharSet=CharSet.Ansi )]
 public struct CMPP_DELIVER
 {
  public CMPP_HEAD Head;
  public UInt64 Msg_ID;
  [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=21)]
  public string Dest_Id;
  [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=10)]
  public string Service_Id;
  public Byte TP_Pid;
  public Byte TP_Udhi;
  public Byte Msg_Fmt;
  [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=10)]
  public string Src_Terminal_Id;
  public Byte Src_Terminal_Type;
  public Byte Registered_Delivery;
  public Byte Msg_Length;
  public string Msg_Content;
  [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=20)]
  public String LinkID;

  public bool Init(Byte[] buffer)
  {
   int iPos=0;
   bool bOK=true;
   try
   {
    Msg_ID=(UInt64)BitConverter.ToUInt64(buffer,0);
    iPos=iPos+8;

    Dest_Id=Utility.Decode(buffer,iPos,21,CODING.ASCII);
    iPos=iPos+21;

    Service_Id=Utility.Decode(buffer,iPos,10,CODING.ASCII);
    iPos=iPos+10;

    TP_Pid=buffer[iPos];
    iPos++;

    TP_Udhi=buffer[iPos];
    iPos++;

    Msg_Fmt=buffer[iPos];
    iPos++;

    Src_Terminal_Id=Utility.Decode(buffer,iPos,32,CODING.ASCII);
    iPos=iPos+32;

    Src_Terminal_Type=buffer[iPos];
    iPos++;

    Registered_Delivery=buffer[iPos];
    iPos++;

    Msg_Length=buffer[iPos];
    iPos++;

    if(Registered_Delivery==0)//是短訊息
    {
     Msg_Content=Utility.Decode(buffer,iPos,Msg_Length,(CODING)Msg_Fmt);

    }
    else//是狀態報表,先轉為BASE64 String 儲存
     Msg_Content=Convert.ToBase64String(buffer,iPos,Msg_Length);
    
    iPos=iPos+Msg_Length;
    LinkID=Utility.Decode(buffer,iPos,20,CODING.ASCII);
   }
   catch
   {
    bOK=false;
   }
   return bOK;

  }
  public CMPP_REPORT GetReport()
  {
   CMPP_REPORT Report=new CMPP_REPORT();
   if(Registered_Delivery==1)//是狀態報表
   {
    Byte[] bytes=Convert.FromBase64String(Msg_Content);
    if((bytes!=null)&&(bytes.Length>0))
     Report.Init(bytes);
   }
   return Report;

  }

 }
 [ StructLayout( LayoutKind.Sequential, Pack=1,CharSet=CharSet.Ansi )]
 public struct CMPP_REPORT
 {
  public UInt64 Msg_Id;
  public string Stat;
  public string Submit_Time;
  public string Done_Time;
  public string Dest_Terminal_Id;
  public UInt32 SMSC_Sequence;

  public bool Init(Byte[] buffer)
  {
   int iPos=0;
   bool bOK=true;
   try
   {
    Msg_Id=(UInt64)Utility.NetBytesToInt(buffer,0,8);
    iPos+=8;

    Stat=Utility.Decode(buffer,iPos,7,CODING.ASCII);
    iPos+=7;

    Submit_Time=Utility.Decode(buffer,iPos,10,CODING.ASCII);
    iPos+=10;

    Done_Time=Utility.Decode(buffer,iPos,10,CODING.ASCII);
    iPos+=10;

    Dest_Terminal_Id=Utility.Decode(buffer,iPos,32,CODING.ASCII);
    iPos+=32;

    SMSC_Sequence=(UInt32)Utility.NetBytesToInt(buffer,iPos,4);
   }
   catch
   {
    bOK=false;
   }
   return bOK;

 

  }
 }
 [ StructLayout( LayoutKind.Sequential, Pack=1,CharSet=CharSet.Ansi )]
 public struct CMPP_DELIVER_RESP
 {
  public CMPP_HEAD Head;
  public UInt64 Msg_Id;
  public UInt32 Result;
  public Byte[] GetBuffer()
  {
   int iPos=0;
   Head.TotalLength=(UInt32)Marshal.SizeOf(this);
   Byte[] buffer=new Byte[Head.TotalLength];
   Byte[] temp=null;
   
   Byte[] HeadBuffer=this.Head.GetBuffer();
   Array.Copy(HeadBuffer,0,buffer,0,HeadBuffer.Length);
   iPos=HeadBuffer.Length;
   
   temp=BitConverter.GetBytes(Msg_Id);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+temp.Length;

   temp=Utility.IntToNetBytes(Result);
   Array.Copy(temp,0,buffer,iPos,temp.Length);
   iPos=iPos+temp.Length;

   return buffer;

  }
 }

 [ StructLayout( LayoutKind.Sequential, Pack=1,CharSet=CharSet.Ansi )]
 public struct CMPP_ACTIVE_TEST_RESP
 {
  public CMPP_HEAD Head;
  public Byte Reserved;
  public Byte[] GetBuffer()
  {
   int iPos=0;
   Head.TotalLength=(UInt32)Marshal.SizeOf(this);
   Byte[] buffer=new Byte[Head.TotalLength];
   
   Byte[] HeadBuffer=this.Head.GetBuffer();
   Array.Copy(HeadBuffer,0,buffer,0,HeadBuffer.Length);
   iPos=HeadBuffer.Length;

   buffer[iPos]=Reserved;

   return buffer;

  }
 }

 [ StructLayout( LayoutKind.Sequential, Pack=1,CharSet=CharSet.Ansi )]
 public struct CMPP_CANCEL
 {
  public CMPP_HEAD Head;
  public UInt64 MsgID;
  public Byte[] GetBuffer()
  {
   Byte[] buffer=new Byte[Marshal.SizeOf(this)];
   Byte[] HeadBuffer=this.Head.GetBuffer();
   int iPos=HeadBuffer.Length;
   Array.Copy(HeadBuffer,0,buffer,0,iPos);
   Byte[] temp=BitConverter.GetBytes(MsgID);
   buffer[iPos+7]=temp[0];
   buffer[iPos+6]=temp[1];
   buffer[iPos+5]=temp[2];
   buffer[iPos+4]=temp[3];
   buffer[iPos+3]=temp[4];
   buffer[iPos+2]=temp[5];
   buffer[iPos+1]=temp[6];
   buffer[iPos+0]=temp[7];

   return buffer;
  }
 }
 [ StructLayout( LayoutKind.Sequential, Pack=1,CharSet=CharSet.Ansi )]
 public struct CMPP_CANCEL_RESP
 {
  public CMPP_HEAD Head;
  public UInt32 SuccessID;
 }

 #endregion

}

【待續】

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.