国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

在CMPP2.0 協議SP端的.NET開發

2019-11-18 12:02:19
字體:
來源:轉載
供稿:網友

  一、CMPP協議簡介
  中國移動通信互聯網短信網關接口協議(China Mobile Peer to Peer CMPP),是中國移動夢網內部各SMS參與節點相互交換SMS的官方協議。作為夢網的參與方,移動夢網的增值服務商(Service PRovider SP )要按照此協議規范實現SP的部分,才可以將自己的短信通過移動的GSM網絡的數據通道傳輸到最終手機用戶上。
  
  實際上,協議規范了3個方面的內容:
  
  SP與移動的互聯網短信網關(Internet Short Message Gateway,ISMG)之間的接口協議
  
  ISMG之間的接口協議(譬如移動各省、市之間的短信息交換通過ISMG之間進行)
  
  ISMG與匯接網關(Gateway Name Server GNS,類似互聯網上的DNS服務器)之間的接口協議,譬如跨省之類的短信需要GNS的幫助指出當前ISMG該如何傳遞短信。
  
  其中,后二方面屬于移動短信息系統內部實現,對于SP來講大概可以“透明”來看待,只要實現了SP同ISMG的正確交互,就可以實現接入移動夢網短信系統。我們關心的只是SP端的開發細節。
  
  二、CMPP交互模式
  從手機用戶角度講,按短信的發起/接收路徑來講,有兩個叫法:
  
  MT(Short Message Mobile Terminated, SMMT),短信接收,短信從SP發送到手機用戶。
  
  MO (Short Message Mobile Originate,SMMO),短信發送,短信從手機用戶端發送到目標SP。
  
  這兩類短信交互,從SP端來看,都是屬于Socket傳輸應用,CMPP的協議是以TCP/ip協議作為底層承載協議的,屬于TCP/IP協議棧之上的應用。
  
  SP同ISMG的交互連接分長連接和短連接。
  
  所謂短連接,就是一次連接,傳輸一個消息,然后等待回復后拆除連接,顯然,效率很低,所以,基本上不被考慮(實際應用移動也不答應SP采用短連接,只是不明白移動為什么還要寫入文檔? ISMG間會需要?)
  
  所謂長連接,就是SP建立同ISMG連接,然后不斷將數據包(一個個CMPP消息)發送到ISMG,此處發送不必等待某條消息的ISMG回應消息返回,就接著發送下一個消息。同時,等待ISMG返回信息或者等待ISMG發送給SP的消息。發送同接收消息不是一定要同步的,實際采用異步(同時也時雙工)模式。從效率上,顯然,必須全雙工的異步模式才能夠滿足實際應用需求。
   在CMPP2.0 協議SP端的.NET開發(圖一)
  三、SP端開發
  1.消息分類
  
  首先,圖中的CMPP消息有很多種,SP同ISMG之間交流這些消息。大體上這些消息發出后,對方往往需要回復一個應答(RESP)類消息。注重,這些消息大多具有方向性,也就是說只能夠從一端到另一端,而不可反方向進行,有些(少數)則可兩端都能夠發出。以下信息主要來源于移動的文檔,但針對大家易混淆或源文檔解釋不夠具體做了明確和補充。具體見下表:
   在CMPP2.0 協議SP端的.NET開發(圖二)
  2.交互階段
  
  整個CMPP協議交互分為驗證、事務兩個階段。驗證階段,發送CMPP_CONNECTION消息進行驗證,通過驗證后(必須要通過才)進入CMPP事務階段,可以發送短信數據了。上表中的CMPP_CONNECTION以下的消息都屬于事務階段的消息。
  
  3.消息數據結構
  
  每一個消息包含 消息頭 和 消息體兩個部分,頭固定長度為12字節,其他消息長度各異,但是同一類型消息的長度是固定的。所有消息的各個字段基本上僅有3種類型:Unsigned Integer (無符號整型) 、Integer(整型)、Octet String(字符串),每種類型具體長度不定,網絡字節順序。
  
  1、消息頭(3個Unsigned Integer字段組成):
  
  4字節的Total_Length (Unsigned Integer),包含了此消息的總計(包括了頭部分)長度。
  
  4字節的Command_Id(Unsigned Integer),指明了此消息到底是什么消息,就是上表中消息的枚舉值。應用程序根據此值確定本數據包到底是什么消息,從而可以按照確定的消息類型,解析余下的消息體。
  
  4字節的Sequence_Id(Unsigned Integer),指明了此數據包在發送此消息端的唯一編號。這個唯一編號,實際上可以看作流水操作編號。因為分析到交互模式我們看到,SP發送數據到ISMG,不是每發送一個就停下來等待ISMG的回復,而是“一下子”發送多個數據包過去,然后等待ISMG的回應。然而,怎么知道回應的消息是到底對應之前發送過去的消息中的那一條呢?本字段就是解決此難題。SP按照編號發送消息過去,等待ISMG的回應—一般情形下回應消息數據結構都有表明本消息回應的是SP發出的哪一條消息,這個對應就是依靠Sequence_Id。它并不要求一定要嚴格唯一,但是在給定的一段時間內,必須唯一(基本上只要SP發送過去的消息中沒有重復就行了)。假如是需要SP回答的消息,SP也必須將ISMG發送過來的消息的Sequence_Id填入相應字段,表明這是某個消息的回應。SP端和ISMG端Sequence_ID都沒有確定具體的算法。SP可以(但不推薦)采用數據庫的唯一Id作為此值。
  
  2、消息體。消息體長度根據消息不同,長度不一。其他的參考移動的文檔《中國移動通信互聯網短信網關接口協議(China Mobile Peer to Peer, CMPP)(V2.0)》,這里著重講講2個重要消息的消息體數據結構:
  
  CMPP-_SUBMIT的消息體:
   在CMPP2.0 協議SP端的.NET開發(圖三)
  CMPP_SUBMIT消息長度是可變的,將SP端的消息發送給ISMG,ISMG將返回一個MSGID給SP標示此消息,之后(48小時以內,但一般最多幾分鐘內就可),ISMG返回關于此消息的遞送報告。遞送報告同MO短消息是通過另外一個重要消息CMPP-_DELIVER來提交給SP的:
  
  CMPP-_DELIVER的各個字段:
   在CMPP2.0 協議SP端的.NET開發(圖四)
  假如是報告,那么Msg_Content將按照狀態報告結構來解釋:
   在CMPP2.0 協議SP端的.NET開發(圖五)
  關于State字段,如下解釋:
  在CMPP2.0 協議SP端的.NET開發(圖六)
  4.安全驗證
  
  CMPP協議在CMPP_CONNECT中傳遞驗證消息。驗證消息為9字節的0+移動給出的密碼+當前時間戳字節數組的md5算法后的字節。時間戳為 月日時分秒,10位。代碼算法如下:
  
  private byte[] getMd5Code()
  
  {
  
  byte[] buf=new byte[6+9+_PassWord.Length+10] ;
  
  byte[] s_a=Encoding.ASCII.GetBytes(_SystemID); //就是企業代碼
  
  byte[] s_0={0,0,0,0,0,0,0,0,0};   //9字節的0,此處當作右補0
  
  byte[] s_p=Encoding.ASCII.GetBytes(_Password); //密碼
  
  this._timestamp =getTimestamp();  //取得認證碼時賦值字符串
  
  byte[] s_t=Encoding.ASCII.GetBytes(_timestamp); //10位字符串字節數組
  
  s_a.CopyTo(buf,0);
  
  s_0.CopyTo(buf,6);
  
  s_p.CopyTo(buf,6+9);
  
  s_t.CopyTo(buf,6+9+_Password.Length);
  
  MD5 md5= new MD5CryptoServiceProvider(); //創建MD5類別
  
  return(md5.ComputeHash(buf,0,buf.Length));
  
  }
  
  其中getTimestamp函數為返回例如“0710125959”(7月10號12點59分59秒)這樣的字符串,具體代碼略過,有愛好請查看本文的附件代碼。
  
  5.廠商API問題
  
  筆者公司所處廣東,廣東移動提供了華為的以C 形式的API(SMEIDLL.dll),來幫助大家初期熟悉CMPP協議。但是,經過開發測試,發現華為的API至少存在幾個問題:
  
  1、封裝成幾個API函數,但是由于CMPP自身的復雜性,導致這些函數丑陋無比,參數多,而且難以明晰含義。華為的API,內部將CMPP的驗證、事務階段分成幾個函數實現,其中將發送SMS到ISMG功能以函數提供,竟然出現SubmitAExExEx之類的函數說明。
  
  2、CMPP的交互是異步的,需要多線程實現一邊發送,一邊接收反饋信息。此API應當是內部維護一個線程進行CMPP_SUBMIT消息發送,但是華為API卻通過空循環之類的操作等待ISMG返回CMPP_SUBMIT_RESP得到相應的MSGID再返回(從而實現消息同步返回)。經過測試,大約需要200毫秒,這個在實際SP的高性能需求場合根本無法滿足系統要求。
  
  3、接收短信必須依靠程序主動先發出函數HasDeliverMessage調用 ,得到有消息才可通過GetDeliverSMEx函數獲取消息,顯然,這種方式是低效率的,而且輕易產生消息數據包丟失,表現為有些MO消息,SP接收不到。而且,令人迷惑的是,你還不能夠新開一個線程專門來做判定并接收MO的動作,實際開發中一旦采用線程來做就回發生內存保護錯誤(大概屬于同API自身的線程有沖突)。
  
  4、返回錯誤碼,往往又是華為自己定的一套錯誤碼(大概華為設計此API為了適應SMGP CMPP等多個協議),而且經常變動,很是傷腦筋。
  
  基于以上理由,我認為自己按照CMPP協議開發一個SP端程序,比較能夠滿足一般SP的需求。
  
  四、C#實現
  1、CMPP協議實現類CMPPClient
  
  通過研究,筆者用C#寫了一組類實現自己的CMPP SP端程序(CMPPClient)。為了實現相關類,還需要編寫一些輔助類,并且首先要解決CMPP協議的數據結構同C#的數據之間的轉換問題。
  
  CMPP的Octet String 實際上相當于C#中的byte[],所有CMPP消息的Octet String字段出了CMPP_SUBMIT和CMPP_DELIVER的msg_content字段外,其他的都可以認為是ASCII編碼,所以全部可以采用System.Text.Encoding.ASCII進行編碼和解碼;對于Msg_Content字段,由于一般情況下存在漢字信息傳輸.,所以默認的編/解碼應該為Encoding.Default,實際是什么編碼還要考察MSG_Fmt字

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 乌拉特中旗| 时尚| 漳州市| 普兰店市| 观塘区| 云龙县| 龙里县| 黑水县| 福安市| 大洼县| 揭东县| 塔城市| 深州市| 扎鲁特旗| 云龙县| 兴业县| 岳阳县| 广汉市| 孝感市| 政和县| 措美县| 新绛县| 肇东市| 兴文县| 普洱| 囊谦县| 樟树市| 双桥区| 仙居县| 宿松县| 长寿区| 孝昌县| 四平市| 丰镇市| 偏关县| 丹凤县| 宁河县| 芦溪县| 洱源县| 剑阁县| 成武县|