CMPP SP端 C.docx

上传人:b****4 文档编号:4260406 上传时间:2022-11-28 格式:DOCX 页数:79 大小:40.51KB
下载 相关 举报
CMPP SP端 C.docx_第1页
第1页 / 共79页
CMPP SP端 C.docx_第2页
第2页 / 共79页
CMPP SP端 C.docx_第3页
第3页 / 共79页
CMPP SP端 C.docx_第4页
第4页 / 共79页
CMPP SP端 C.docx_第5页
第5页 / 共79页
点击查看更多>>
下载资源
资源描述

CMPP SP端 C.docx

《CMPP SP端 C.docx》由会员分享,可在线阅读,更多相关《CMPP SP端 C.docx(79页珍藏版)》请在冰豆网上搜索。

CMPP SP端 C.docx

CMPPSP端C

CMPPSP端C#实例(转)

//附CMPPClient.cs:

/*

作者:

TNT 时间:

2003年12月

文件说明:

本文件实现SP端的协议开发。

*/

using System;

using System.Security.Cryptography;  

using System.Net.Sockets; 

using System.Net;

using System.Text; 

using System.Threading; 

using System.Collections; 

namespace CMPP.YOURCOMPANY

{

 public delegate void ReportEventHandler(object sender, ReportEventArgs e);  //声明一个事件的指代(指针)

 public delegate void SMSEventHandler(object sender, SMSEventArgs e);   //声明一个事件的指代(指针)

 public delegate void TerminateEventHandler(object sender,TerminateEventArgs e);   //声明收到终止信号

 public delegate void TerminateRespEventHandler(object sender,TerminateRespEventArgs e);  //回应事件发生

 public delegate void TestEventHandler(object sender,TestEventArgs e);

 public delegate void TestRespEventHandler(object sender,TestRespEventArgs e);

 public delegate void ConnectRespEventHandler(object sender,ConnectRespEventArgs e);

 public delegate void CancelRespEventHandler(object sender,CancelRespEventArgs e);

 public delegate void SubmitRespEventHandler(object sender,SubmitRespEventArgs e);

 public delegate void QueryRespEventHandler(object sender,QueryRespEventArgs e);

 public delegate void LogonSuccEventHandler(object sender,EventArgs e); //当成功登录系统

 public delegate void SocketClosedEventHandler(object sender,EventArgs e); //当套接字被检测到关闭

 public delegate void FailedItemDeletedEventHandler(object sender,WaitingQueueItemEventArgs e); //当一条等待队列的消息超过60秒没有回应

 

 public delegate void CMPPClientSvcStopEventHandler(object sender, ClientQueueStateArgs e); //当CMPP服务停止时候触发事件

 /// 

 /// 作为CMPP协议的客户端,具有的登陆、发送、接受功能

 /// 会开3 个线程处理:

 1、处理需要发送 MO(下行)的消息 

 ///       2、处理从移动服务器发送过来CMPP的消息

 ///       3、处理连接断等信息,检查需要重发的消息,检查收到的报告、短信,并调用 OnReport 事件 OnSMS事件

 /// 

 public class CMPPClient

 { 

  public static long CMPP_ACTIVE_TEST_C_TICKs= 30  ;  // *3 ;  //长连接的active_test测试时间

  public static long CMPP_ACTIVE_TEST_T_TICKs= 60 ;    // 消息失败时间 60秒

  public static int CMPP_ACTIVE_TEST_N_COUNT=3;  //3次  

  //public static int CMPP_MSG_MAX=100;   //一次取得的最大消息数量

  public static int CMPP_Port=7890;

  

  public event ReportEventHandler onReportHandler;   //指向事件处理代码的指针

  public event SMSEventHandler onSMSHandler;     //短信到来处理

  public event TestEventHandler onTestHandler;

  public event TestRespEventHandler onTestRespHandler;

  public event ConnectRespEventHandler onConnectRespHandler;

  public event CancelRespEventHandler onCancelRespHandler;

  public event TerminateEventHandler onTerminateHandler;

  public event TerminateRespEventHandler onTerminateRespHandler;

  public event SubmitRespEventHandler onSubmitRespHandler;

  public event QueryRespEventHandler onQueryRespHandler;

  public event LogonSuccEventHandler onLogonSuccEventHandler;

  public event SocketClosedEventHandler onSocketClosedHandler;

  public event FailedItemDeletedEventHandler onWaitingItemDeltedHandler; //当等待队列消息超时

  

  public event CMPPClientSvcStopEventHandler onClientSvcStopedHandler;  //当服务停止时候的事件

  //private 函数区域//////////////////////////////////////////////////////////////////////

  private Socket  tcp=null;     

  private IPHostEntry ip=null;   

  private IPEndPoint  cmpp_ep=null;   

  private int   RecvTimeOut =1000;       //2000ms的接受超时

  private int   SendTimeout =2000;       //2000ms的发送超时 

  private string  CMPP_Server="";   //移动的服务器IP或者DNS名

  private string  systemID="";   //企业编号

  private string  userName="";   //sp的号码 /企业编号

  private string  PassWord="";   //口令 

  private bool  isStop=false;   //本服务是否终止运行

  private bool  isLogin=false;   //是否已经登录    

  private Thread  Send_Thread;   //发送线程,专门处理对移动的数据包

  private Thread  Recv_Thread;   //专门处理接收包

  private Thread  Deamo_Thread;   //监控线程

  private string  ErrorInfo="";   //存放最后一次发生的错误信息 或者参考信息      

  private DateTime _current_time=DateTime.Now;     //上一次 ping的时间  

  private uint  lastSequence;   //流水号,每一次重新启动都需要重新设定 lastSequence

  private SortedList _outSeqQueue=new SortedList();   //消息队列存储 QueueItem,存储发送队列中的状态

  private SortedList  _waitingSeqQueue=new SortedList(); //消息队列存储 QueueItem

  private int   sub_resp=0;       //最后返回的包 Sequence

  private DateTime _lastOkTime;      //最后正确发送消息时间

  private bool  _bNre=false;      //空引用错误,套接字错误

 

  //private ManualResetEvent _connectionDone=new ManualResetEvent(false); //是否连接到套接字服务器,也就是CMPP服务器

  //private ManualResetEvent _lastsendDone=new ManualResetEvent(false);  //上一次发送是否完毕

  //private ManualResetEvent _lastrecvDone=new ManualResetEvent(false);  //上一次接收是否完毕

      

  private void ping()    //发送一次ping包 ,不经过_outSeqQueue 直接存储在 out queue中

  { 

   uint seq=this.getNextSequence(); 

   MSG.CMPP_MSG_TEST test=new MSG.CMPP_MSG_TEST(seq); 

   QueueItem q=new QueueItem(seq,(uint)MSG.CMPP_COMMAND_ID.CMPP_ACTIVE_TEST,0,0); 

   q.setmsgObj(test); 

   this.addToOutQueue(q);

  }

   

  private string getValIdTime(DateTime d)        //返回短信存活时间

  {

   DateTime n=d.AddHours

(2); //2小时

   return(n.Year.ToString().Substring

(2) + n.Month.ToString().PadLeft(2,'0')+n.Day.ToString().PadLeft(2,'0')+n.Hour.ToString().PadLeft(2,'0')+n.Minute.ToString().PadLeft(2,'0')+n.Second.ToString().PadLeft(2,'0')+"032+");            

  }

 

  private bool isPingTime( )  //是否到了ping一次的时间

  {

   System.TimeSpan   l=(DateTime.Now - this._current_time );

   

   if ( l.TotalSeconds >= (CMPPClient.CMPP_ACTIVE_TEST_C_TICKs))

   {    

    lock(this)

    {

     this._current_time =DateTime.Now;        

     return(true);

    }

   }

   else

   {

    return(false);

   }

  }

 

  private void checkReSend()    //是否需要再一次ping //查询 _waitingSeqQueue 是否存在 上一次 没有相应的消息

  {   //调查waiting queue 中的所有消息,如果入列时间超过60 

   for(int i=0;i

   {

    Thread.Sleep(20); 

    QueueItem q=(QueueItem)this._waitingSeqQueue.GetByIndex(i);   

    if(q!

=null)

    {

     DateTime this_time=DateTime.Now ; //去当前时间

     TimeSpan t=this_time-q.inQueueTime ; 

     if(t.TotalSeconds >CMPPClient.CMPP_ACTIVE_TEST_T_TICKs ) //达到超时时间

     {//需要重新发送消息

      if(q.FailedCount>=CMPPClient.CMPP_ACTIVE_TEST_N_COUNT)

      {

       //报告消息发送失败

       if(this.onWaitingItemDeltedHandler!

=null)

       {

        WaitingQueueItemEventArgs e=new WaitingQueueItemEventArgs(q);

        this.onWaitingItemDeltedHandler(this,e); 

       }

       this.delFromWaitingQueue(q); //从等待队列中删除 

       //q.MsgState =(int)MSG_STATE.SENDED_WAITTING; 

      }

      else

      {//可以尝试继续发送

       q.inQueueTime = this_time;

       q.FailedCount ++ ;

       q.MsgState =(int)MSG_STATE.SENDED_WAITTING ;

       this.sendQueueItem(q);      

      }

     }      

    }

   }    

  

  }

 

  private void startThreads()

  {

   Deamo_Thread=new Thread(new ThreadStart(this.DeamonThread));

   Deamo_Thread.Start(); 

  }

 

  private QueueItem newQueueItem(int msgtype,int msgstate,object msg)  //生成一个消息队列成员对象实例

  {

   uint seq=this.getNextSequence();   // 

   QueueItem q=new QueueItem(seq,(uint)msgtype,0,msgstate);

   q.setmsgObj(msg);       //设定消息为 object

   return(q);

  }

 

  private QueueItem getOutQueueItem(uint seq)  //获取MT 队列中的消息项目

  {

   lock(this)

   {

    return((QueueItem)this._outSeqQueue[seq]) ; 

   }

  }

 

  private QueueItem getWaitingQueueItem(uint seq)  //获取等待队列中的消息

  {

   return((QueueItem) this._waitingSeqQueue[seq]);

  }

        

  private void addToOutQueue(QueueItem q)

  {

   lock(this)

   {

    this._outSeqQueue.Add(q.Sequence,q);     

   }

  }

 

  private void addToWaitingQueue(QueueItem q)

  {

   lock(this)

   {

    if(!

this._waitingSeqQueue.ContainsKey(q.Sequence))

    {

     this._waitingSeqQueue.Add(q.Sequence,q);   

    }

   }

  }

 

  private QueueItem getTopOutQueue()     //需要在取之前进行判断

  {

   for(int i=0;i

   {

    QueueItem q=(QueueItem)this._outSeqQueue.GetByIndex(i);   

    if(q!

=null)

    {

     if(q.MsgState==(int)MSG_STATE.NEW)  //新消息,立即返回

     {

      lock(this)

      {

       q.MsgState =(int)MSG_STATE.SENDING; //发送状态 

      }

      return(q);   

     }

     else

     {

      q=null;

     }

    }

   }    

   return(null);

  }

 

  private ArrayList getTop16Queue() //返回16条最顶的消息

  {

   int arrlength=0;

   ArrayList reArr=new ArrayList() ;

   QueueItem q=getTopOutQueue();

   while(q!

=null || arrlength <= 16)

   {    

    if(q!

=null)

    {

     reArr.Add(q);

     arrlength++;

    }

    else

    {

     break;

    }

    q=getTopOutQueue();

   }

   

   if(arrlength>0)

   {

    return(reArr);   

   }

   else

   {

    return(null);

   }

  }

 

  private void delFromOutQueue(QueueItem  q)

  {

   lock(this)

   {

    this._outSeqQueue.Remove(q.Sequence);   

   }

  }

 

  private void delFromOutQueue(uint seq)

  {

   lock(this)

   {

    this._outSeqQueue.Remove(seq);  

   }

  }

 

  private void delFromWaitingQueue(QueueItem q)

  {

   lock(this)

   {

    this._waitingSeqQueue.Remove(q.Sequence);  

   } 

  }

 

  private void delFromWaitingQueue(uint seq)

  {

   this._waitingSeqQueue.Remove(seq);  

  }

 

  private void  SendLogin(string SystemID,string spNum,string Password) 

  {//发送登录验证包    

   systemID=SystemID;

   userName=spNum;

   PassWord=Password; 

   uint seq=this.getNextSequence(); //取得一个流水号 

   MSG.CMPP_MSG_CONNECT cn=new MSG.CMPP_MSG_CONNECT(seq);

   cn.Password =Password.Trim();

   cn.SourceAdd =SystemID.Trim();

   tcp.Send(cn.ToBytes()); 

  }

 

  private byte[]  prepairPKs(QueueItem outitem)//将QueueItem发送出去

  {

   uint seq=outitem.Sequence ;

   uint msgtype=outitem.MsgType;  

   switch(msgtype)

   {

    case (uint)MSG.CMPP_COMMAND_ID.CMPP_ACTIVE_TEST :

     MSG.CMPP_MSG_TEST test=(MSG.CMPP_MSG_TEST) outitem.getMsgObj(); //发送队列中取出

     lock(this)

     {

      outitem.MsgState =(int)MSG_STATE.SENDING;

      this.delFromOutQueue(seq);

      this.addToWaitingQueue(outitem);    //等待服务器的active_TEST_resp 

     }

     outitem.MsgState =(int)MSG_STATE.SEN

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1