移动CMPP3.0解Deliver包(C#版)

///线程处理接收到的数据

private void RecvISMGMsgThread()   //处理ISMG消息的线程 
  {  
   while(!this.isStop )  
   {    
    try   
    {         
     byte[] rbuf=new byte[10240]; //结果缓冲区    
     byte[] recv_temp=new Byte[1024]; //recv临时缓冲区   
     int index=0;  
     //int hlen=0;
     int msglength=NetTCP.Receive(rbuf);  //阻塞接收//分析收到的数据
     CMPP.StateObject.CMPP_MSG_Header header;  //=new CMPP.StateObject.CMPP_MSG_Header(rbuf,index);
     //取得一个消息                        
     while(index<msglength) //逐个消息分析    
     {    
      header=new CMPP.StateObject.CMPP_MSG_Header(rbuf,index); //取得一个消息            
      byte[] the_pk= new byte[header.MSGLength] ;   //生成此消息的大小     
      //hlen=header.MSGLength;
      for(int i=0;i<header.MSGLength ;i++)     
      {      
       the_pk[i]=rbuf[index++];     
      }            
      uint seq; //取得回复消息的下一个流水序列号     
      switch(header.Command_ID)     
      {      
       case (uint)CMPP.StateObject.CMPP_COMMAND_ID.CMPP_ACTIVE_TEST : //服务器给客户的测试信号       
        this.ErrorInfo =this.ErrorInfo +"/r/n"
         +"收到:CMPP_ACTIVE_TEST";       
        CMPP.StateObject.CMPP_MSG_TEST test=new CMPP.StateObject.CMPP_MSG_TEST(the_pk);       
        seq=test.Sequence;       //取得发送过来的流水号       
        CMPP.StateObject.CMPP_MSG_TEST_RESP test_reply=new CMPP.StateObject.CMPP_MSG_TEST_RESP(seq);          
        //服务器CMPP_ACTIVE_TEST
        MOMessageArgs sertestre=new MOMessageArgs(
         "CMPP_ACTIVE_TEST",false,seq.ToString());
        onMOMessageEventHandler(this,sertestre);
      
        //回应
        NetTCP.Send(test_reply.toBytes());    //马上送出回应包,不需要进入队列         
        if(this.onTestHandler!=null)       
        {        
         TestEventArgs e=new TestEventArgs(test);       
         onTestHandler(this,e);       
        }      
        else       
        {        
         defaultTestEventHandler();       
        }       
        this.ErrorInfo =this.ErrorInfo +"/r/n"
         +"发送:CMPP_ACTIVE_TEST_RESP ";       
        break;       
       case (uint)CMPP.StateObject.CMPP_COMMAND_ID.CMPP_ACTIVE_TEST_RESP : //服务器的回应消息,应当丢弃不管       
        this.ErrorInfo =this.ErrorInfo +"/r/n"
         +("收到:CMPP_ACTIVE_TEST_RESP ");       
        CMPP.StateObject.CMPP_MSG_TEST_RESP test_reply2=new CMPP.StateObject.CMPP_MSG_TEST_RESP(the_pk); //构造消息       
        seq=test_reply2.Sequence;    //寻找 曾经发送过去的消息                
        this.delFromWaitingQueue(seq);      //删除等待队列中的消息 //清空等待回应队列       
        if(this.onTestRespHandler!=null)       
        {   
         //本地测试消息回应
         TestRespEventArgs e=new TestRespEventArgs(test_reply2);         
         onTestRespHandler(this,e);       
        }       
        else       
        {        
         
         defaultTestRespEventHandler();       
        }      
        break;       
       case (uint)CMPP.StateObject.CMPP_COMMAND_ID.CMPP_CANCEL_RESP :       
        this.ErrorInfo =this.ErrorInfo +"/r/n"
         +("收到:CMPP_CANCEL_RESP ");
        CMPP.StateObject.CMPP_MSG_CANCEL_RESP cancel_reply=new CMPP.StateObject.CMPP_MSG_CANCEL_RESP(the_pk);//构造消息       
        seq=cancel_reply.Sequence;       
        this.delFromWaitingQueue(seq);       
        if(this.onCancelRespHandler!=null)       
        {        
         CancelRespEventArgs e=new CancelRespEventArgs(cancel_reply);         
         onCancelRespHandler(this,e);        
        }       
        else       
        {        
         defaultCancelRespEventHandler();       
        }       
        break;       
       case (uint)CMPP.StateObject.CMPP_COMMAND_ID.CMPP_CONNECT_RESP :   //检查下消息的正确性,清除等待队列 设定连接成功标志       
        this.ErrorInfo =this.ErrorInfo +"/r/n"
         +("收到:CMPP_CONNECT_RESP ");        
        CMPP.StateObject.CMPP_MSG_CONNECT_RESP cn_reply=new CMPP.StateObject.CMPP_MSG_CONNECT_RESP(the_pk);       
        seq=cn_reply.Sequence;     //取得消息的seq       
//        if(this.onConnectRespHandler !=null)       
//        {        
//         ConnectRespEventArgs e=new ConnectRespEventArgs(cn_reply);        
//         onConnectRespHandler(this,e);       
//        }       
//        else       
//        {        
//         defaultConnectRespEventHandler();       
//        } 
        ConnectRespEventArgs cne=new ConnectRespEventArgs(cn_reply);        
        onConnectRespHandler(this,cne);
 
        defaultConnectRespEventHandler();       
        if(cn_reply.isOk)       
        {        
         this.isLogin  =true;       
        }       
        else       
        {        
         this.isLogin  =false;       
        }       
        this.delFromWaitingQueue(seq);    //删除队列中的等待连接信息包       
        break;       
       case (uint)CMPP.StateObject.CMPP_COMMAND_ID.CMPP_DELIVER:    //检查消息正确定,立即返回 正确 或者 失败,正确则处理是否状态包,不是状态包则存到MO缓存,表示收到信息,时状态包则判断缓存消息进行消息送达处理       
        this.ErrorInfo =this.ErrorInfo +"/r/n"
         +("收到:CMPP_DELIVER ");        
        //BIConvert.DumpBytes(the_pk,"c://CMPP_DELIVER.txt");//保留映像      
        CMPP.StateObject.CMPP_MSG_DELIVER deliver=new CMPP.StateObject.CMPP_MSG_DELIVER(the_pk);              
        seq=(uint)deliver.ISMGSequence;       //发过来的流水号,需要立即发送一个deliver_resp      
        //一条 ISMG--〉SP 的消息
        CMPP.StateObject.CMPP_MSG_DELIVER_RESP deliver_resp=new StateObject
         .CMPP_MSG_DELIVER_RESP(seq); 
        //回应ISMG的Deliver消息
        deliver_resp.MsgID =deliver.MsgID ;       
        deliver_resp.Result =0;       
        byte[] t=deliver_resp.toBytes();       
        NetTCP.Send(t);       
        this.ErrorInfo =this.ErrorInfo +"/r/n"
         +("发送:CMPP__DELIVER_RESP ");        
        if(deliver.isReport)       
        {     
         //删除等待队列的消息//报告消息已经正确发送到               
         UInt64 ReportMsgID=deliver.ReportMsgID ; //取得消息ID ,更新 MsgID        
         string StateReport=deliver.StateReport; //取得关于此消息的状态         
         //
         _debugBs(the_pk);        
         ReportEventArgs arg=new ReportEventArgs(the_pk,
          CMPP.StateObject.CMPP_MSG_Header.HeaderLength+8+21+10+1+1+1+32+1+1+1);   
         //构造报告事件参数        
         //ReportEventArgs arg=new ReportEventArgs(ReportMsgID.ToString() );      
         //ReportEventArgs传递的字节数组是 报告信息包的数据,在此不考虑多个报告的情况        
         if(this.onReportHandler!=null)
         { 
          onReportHandler(this,arg);        
         }        
         else        
         {          
          this.defaultReportHandler();          
         }       
        }       
        else       
        {
         //SMSEventArgs 传递的整个deliver包        
         SMSEventArgs smsarg=new SMSEventArgs (the_pk,
          CMPP.StateObject.CMPP_MSG_Header.HeaderLength);          
         if(this.onSMSHandler!=null)        
         {         
          onSMSHandler(this,smsarg);   //触发事件,应当很快结束处理,不要靠考虑存储之类的耗费资源事宜       
         }        
         else        
         {         
          defaultSMSHandler();        
         }       
        }           
        break;        
       case (uint)CMPP.StateObject.CMPP_COMMAND_ID.CMPP_QUERY_RESP :      
        this.ErrorInfo =this.ErrorInfo +"/r/n"
         +("收到:CMPP_QUERY_RESP ");         //收到消息,处理后存入数据库      
        CMPP.StateObject.CMPP_MSG_QUERY_RESP query_resp=new CMPP.StateObject.CMPP_MSG_QUERY_RESP(the_pk);       
        this.delFromWaitingQueue(query_resp.Sequence );   //将等待的队列中的元素删除       
        if(this.onQueryRespHandler!=null)       
        {        
         QueryRespEventArgs e=new QueryRespEventArgs(query_resp);        
        }       
        else       
        {        
         defaultQueryRespEventHandler();      
        }       
        break;   
       case (uint)CMPP.StateObject.CMPP_COMMAND_ID.CMPP_SUBMIT_RESP :    //收到服务器送达的慧英消息       
        this.ErrorInfo =this.ErrorInfo +"/r/n"
         +("收到:CMPP_SUBMIT_RESP ");
        CMPP.StateObject.CMPP_MSG_SUBMIT_RESP submit_resp=new StateObject
         .CMPP_MSG_SUBMIT_RESP(the_pk);         
        BIConvert.DumpBytes(the_pk,"c://CMPP_SUBMIT_RESP.txt");//保留映像       
        //BIConvert.DumpBytes(initValue,"c://CMPP_SUBMIT_RESP.txt");//保留映像      
        sub_resp++; //该变量仅供测试使用      
        delFromWaitingQueue(submit_resp.Sequence);  //删除需要等待的消息       
        if(this.onSubmitRespHandler!=null)       
        {        
         SubmitRespEventArgs e=new SubmitRespEventArgs(submit_resp);        
         //submit_resp.
         onSubmitRespHandler(this,e);       
        }      
        else       
        {         
         defaultSubmitRespEventHandler();       
        }        
        break;       
       case (uint)CMPP.StateObject.CMPP_COMMAND_ID.CMPP_TERMINATE :       
        this.ErrorInfo =this.ErrorInfo
         +"/r/n"+"收到:CMPP_TERMINATE";       
        CMPP.StateObject.CMPP_MSG_TERMINATE terminate=new StateObject
         .CMPP_MSG_TERMINATE(the_pk);       
        seq=terminate.Sequence;       
        CMPP.StateObject.CMPP_MSG_TERMINATE_RESP  terminate_resp=new StateObject
         .CMPP_MSG_TERMINATE_RESP(seq);       
        this.ErrorInfo =this.ErrorInfo +"/r/n"
         +"收到:CMPP_TERMINATE_RESP";       
        NetTCP.Send(terminate_resp.toBytes());         
        if(this.onTerminateHandler!=null)       
        {        
         TerminateEventArgs e=new TerminateEventArgs(
          terminate);        
         onTerminateHandler(this,e);        
         this.StopMe() ; //准备自我停止?       
        }      
        else       
        {        
         defaultTerminateEventHandler();       
        }       
        this._StopMe();  //发出终止设定               
        return;   //退出线程               
       case (uint)CMPP.StateObject.CMPP_COMMAND_ID.CMPP_TERMINATE_RESP :       
        this.ErrorInfo =this.ErrorInfo +"/r/n"+"收到:CMPP_TERMINATE_RESP";       
        CMPP.StateObject.CMPP_MSG_TERMINATE_RESP ter_resp=new CMPP.StateObject.CMPP_MSG_TERMINATE_RESP(the_pk);       
        seq=ter_resp.Sequence ;  //取得流水信号       
        this.delFromOutQueue(seq);   //删除输出表重点项目        
        if(this.onTerminateRespHandler!=null)       
        {        
         TerminateRespEventArgs e=new TerminateRespEventArgs(ter_resp);        
         onTerminateRespHandler(this,e);       
        }       
        else       
        {        
         defaultTerminateRespEventHandler();       
        }       
        this._StopMe();        
        break;     
      }                 
     }         
     LogLastOkTime(DateTime.Now );  //记录当前最后一次消息soket正确时间   
    }   
    catch(SocketException se)   
    {      //超时 
     this.ErrorInfo+=se.Message+"/r/n";
    }   
    Thread.Sleep(50);  
   }    
  } 

///解得Deliver各段数据

public CMPP_MSG_DELIVER(byte[] bs)  
   {         
    header=new CMPP.StateObject.CMPP_MSG_Header(bs);   
    int index=CMPP.StateObject.CMPP_MSG_Header.HeaderLength;       
    this._msgid   =  BitConverter.ToUInt64(bs,index);   
    index+=8;  
    this._destid = Encoding.ASCII.GetString(bs,index,21);    
    index=index+21;  
    this._svccode =Encoding.ASCII.GetString(bs,index,10);    
    index=index+10;  
    this._tpid =(int) bs[index++];  
    this._udhi =(int) bs[index++];   
    this._msgfmt=(int) bs[index++];   
    this._srctid =Encoding.ASCII.GetString(bs,index,21);   
    //index+=21;   
    index+=32;
    index++;
    if(bs[index++]==1)  
    {    
     this._isReport =true;  
    }   
    else   
    {    
     this._isReport =false;  
    }   
    //this._msglength =(int) bs[index++];  
    this._msglength =Convert.ToInt32( bs[index++]);  
    if(! this._isReport )  
    {    
     switch(this._msgfmt )    
     {     
      case (int) CMPP.StateObject.Msg_Format.ASCII :      
       this._msg = Encoding.ASCII.GetString(bs,index,this._msglength );     
       index+=this._msglength ;      
       break;     
      case (int)CMPP.StateObject.Msg_Format.BINARY :      
       this._msg = Encoding.Default.GetString (bs,index,this._msglength );      
       index+=this._msglength ;      
       break;      
      case (int)CMPP.StateObject.Msg_Format.GB2312  :      
       //this._msg = Encoding.Default.GetString(bs,index,this._msglength );      
       this._msg = Encoding.Default.GetString(bs,index,int.Parse((this.header.MSGLength-12-index-20).ToString()) );      
       index+=this._msglength ;      
       break;      
      case (int)CMPP.StateObject.Msg_Format.UCS2 :      
       this._msg = Encoding.BigEndianUnicode.GetString(bs,index,this._msglength );      
       index+=this._msglength ;     
       break;      
      default:      
       break;   
     }
     //LINKID
     this._linkID=Encoding.ASCII.GetString(bs,index,20);
     index+=20;
    }
    else   
    {
     //状态报告    
     this._reportForMsgid = BitConverter.ToUInt64(bs,index);    
     index+=8;    
     this._reportState   = BitConverter.ToString(bs,index,7);    
     index+=7;    
     this._submitTime =  BitConverter.ToString(bs,index,10);   
     index+=10;    
     this._doneTime  =   BitConverter.ToString(bs,index,10);    
     index+=10;    
     this._reportDesttid  = BitConverter.ToString(bs,index,21);   
     index+=21;    
     this._smscSequence   =(int) BIConvert.Bytes2UInt(bs,index );   
    }  
   }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
.Net/C# 实现 中国移动 CMPP v3.0 ISMG SP 收发短信的 SP 客户端 (第2)(CMPP SP Client) 增加了 CMPP 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 8.4.7 链路检测 (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 可采用《中国移动通信 CMPP v3.0 短消息网关模拟器 v1.10》进行测试: 下载于: 《北京风起水流软件工作室》 http://www.zealware.com/download/cmpp3smg.rar本程序以熟悉理 CMPP 3.0 协议为主要目的,只将 "消息定义" 对象化,其相关协议级交互并未作更深层次的 OO! 也暂无任何错误处理程序! 消息定义的所有字段名称及其数据类型均与上述之 CMPP v3.0.0 文档完全一致! 其间参阅过 shanhe@CSDN or yexiong@cnBlogs 大作(在此鸣谢): http://blog.csdn.net/shanhe/archive/2004/07/19/45383.aspx http://cnblogs.com/yexiong/articles/115330.aspx 但其中有些消息定义字节错位,因此不能正常交互?!且对象化层次较高,不利于理协议本身! 遂自己动手,丰衣足食,实现部分主要协议(SP 收发短信):
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值