📄 12.htm
字号:
<td><a class=h_menu href='news_list.asp?action=more&c_id=7'>本站动态</a></td>
<td><a class=h_menu href='user_main.asp'>用户中心</a></td>
<td><b><a class=h_menu href='forum.asp'>深刻论坛</a></b></td>
</tr></table></td></tr>
</table>
<table border=0 cellpadding=0 cellspacing=0 width='98%' align=center>
<tr><td align=left height=30 width='80%'>今天是:2005年09月30日 星期五 您现在位于: <a href='./'>首页</a> → <a href='article.asp'>技术文章</a> → <font title='.Net(C#)'>.Net(C#)</font>
</td><td width='20%' align=right><div id=div_msg><marquee scrolldelay=100 scrollamount=3 onMouseOut='if (document.all!=null){this.start()}' onMouseOver='if (document.all!=null){this.stop()}'><a href=register.asp>[<font class=red>好消息</font>]深刻源码中心大量源码下载</a></marquee></div></td></tr></table>
</td><td width=1 class=bg_frame></td></tr></table><table border=0 width='777' cellspacing=0 cellpadding=0><tr><td width=1 class=bg_frame></td><td width=* align=center class=bg><table border=0 width='100%' cellspacing=0 cellpadding=0><tr><td height=300 align=center class=bg_1>
<table cellspacing=0 cellpadding=1 class=table0>
<tr><td class=td> <img border=0 src='skin/skin_2/small/m_article.gif' align=absmiddle> c#开发手机程序</td></tr>
<tr class=bg_tds><td align=right height=20 class=gray>作者:TNT 出处:CSDN 更新时间: 2005年01月28日 </td></tr>
<tr class=bg_td><td align=center>
<table border=0 class=tablew><tr><td>
<table border=0 width='100%' class=tf><tr><td class=bw><font id="font_word" class=htd style="font-size:14px; font-family:宋体, Verdana, Arial, Helvetica, sans-serif;">文件说明:本文件实现SP端的协议开发。<br>*/<br>using System;<br>using System.Security.Cryptography;  <br>using System.Net.Sockets; <br>using System.Net;<br>using System.Text; <br>using System.Threading; <br>using System.Collections; <br><br>namespace CMPP.YOURCOMPANY<br>{<br> public delegate void ReportEventHandler(object sender, ReportEventArgs e);  //声明一个事件的指代(指针)<br> public delegate void SMSEventHandler(object sender, SMSEventArgs e);   //声明一个事件的指代(指针)<br> public delegate void TerminateEventHandler(object sender,TerminateEventArgs e);   //声明收到终止信号<br> public delegate void TerminateRespEventHandler(object sender,TerminateRespEventArgs e);  //回应事件发生<br> public delegate void TestEventHandler(object sender,TestEventArgs e);<br> public delegate void TestRespEventHandler(object sender,TestRespEventArgs e);<br> public delegate void ConnectRespEventHandler(object sender,ConnectRespEventArgs e);<br> public delegate void CancelRespEventHandler(object sender,CancelRespEventArgs e);<br> public delegate void SubmitRespEventHandler(object sender,SubmitRespEventArgs e);<br> public delegate void QueryRespEventHandler(object sender,QueryRespEventArgs e);<br> public delegate void LogonSuccEventHandler(object sender,EventArgs e); //当成功登录系统<br> public delegate void SocketClosedEventHandler(object sender,EventArgs e); //当套接字被检测到关闭<br> public delegate void FailedItemDeletedEventHandler(object sender,WaitingQueueItemEventArgs e); //当一条等待队列的消息超过60秒没有回应<br> <br><br> public delegate void CMPPClientSvcStopEventHandler(object sender, ClientQueueStateArgs e); //当CMPP服务停止时候触发事件<br><br> /// <summary><br> /// 作为CMPP协议的客户端,具有的登陆、发送、接受功能<br> /// 会开3 个线程处理: 1、处理需要发送 MO(下行)的消息 <br> ///       2、处理从移动服务器发送过来CMPP的消息<br> ///       3、处理连接断等信息,检查需要重发的消息,检查收到的报告、短信,并调用 OnReport 事件 OnSMS事件<br> /// </summary><br> public class CMPPClient<br> { <br>  public static long CMPP_ACTIVE_TEST_C_TICKs= 30    // *3   //长连接的active_test测试时间<br>  public static long CMPP_ACTIVE_TEST_T_TICKs= 60     // 消息失败时间 60秒<br>  public static int CMPP_ACTIVE_TEST_N_COUNT=3;  //3次  <br>  //public static int CMPP_MSG_MAX=100;   //一次取得的最大消息数量<br>  public static int CMPP_Port=7890;<br>  <br>  public event ReportEventHandler onReportHandler;   //指向事件处理代码的指针<br>  public event SMSEventHandler onSMSHandler;     //短信到来处理<br>  public event TestEventHandler onTestHandler;<br>  public event TestRespEventHandler onTestRespHandler;<br>  public event ConnectRespEventHandler onConnectRespHandler;<br>  public event CancelRespEventHandler onCancelRespHandler;<br>  public event TerminateEventHandler onTerminateHandler;<br>  public event TerminateRespEventHandler onTerminateRespHandler;<br>  public event SubmitRespEventHandler onSubmitRespHandler;<br>  public event QueryRespEventHandler onQueryRespHandler;<br>  public event LogonSuccEventHandler onLogonSuccEventHandler;<br>  public event SocketClosedEventHandler onSocketClosedHandler;<br>  public event FailedItemDeletedEventHandler onWaitingItemDeltedHandler; //当等待队列消息超时<br>  <br>  public event CMPPClientSvcStopEventHandler onClientSvcStopedHandler;  //当服务停止时候的事件<br><br>  //private 函数区域//////////////////////////////////////////////////////////////////////<br>  private Socket  tcp=null;     <br>  private IPHostEntry ip=null;   <br>  private IPEndPoint  cmpp_ep=null;   <br>  private int   RecvTimeOut =1000;       //2000ms的接受超时<br>  private int   SendTimeout =2000;       //2000ms的发送超时 <br>  private string  CMPP_Server=<i>"</i><i>"</i>;   //移动的服务器IP或者DNS名<br>  private string  systemID=<i>"</i><i>"</i>;   //企业编号<br>  private string  userName=<i>"</i><i>"</i>;   //sp的号码 /企业编号<br>  private string  PassWord=<i>"</i><i>"</i>;   //口令 <br>  private bool  isStop=false;   //本服务是否终止运行<br>  private bool  isLogin=false;   //是否已经登录    <br>  private Thread  Send_Thread;   //发送线程,专门处理对移动的数据包<br>  private Thread  Recv_Thread;   //专门处理接收包<br>  private Thread  Deamo_Thread;   //监控线程<br>  private string  ErrorInfo=<i>"</i><i>"</i>;   //存放最后一次发生的错误信息 或者参考信息      <br>  private DateTime _current_time=DateTime.Now;     //上一次 ping的时间  <br>  private uint  lastSequence;   //流水号,每一次重新启动都需要重新设定 lastSequence<br>  private SortedList _outSeqQueue=new SortedList();   //消息队列存储 QueueItem,存储发送队列中的状态<br>  private SortedList  _waitingSeqQueue=new SortedList(); //消息队列存储 QueueItem<br>  private int   sub_resp=0;       //最后返回的包 Sequence<br>  private DateTime _lastOkTime;      //最后正确发送消息时间<br>  private bool  _bNre=false;      //空引用错误,套接字错误<br> <br>  //private ManualResetEvent _connectionDone=new ManualResetEvent(false); //是否连接到套接字服务器,也就是CMPP服务器<br>  //private ManualResetEvent _lastsendDone=new ManualResetEvent(false);  //上一次发送是否完毕<br>  //private ManualResetEvent _lastrecvDone=new ManualResetEvent(false);  //上一次接收是否完毕<br>      <br>  private void ping()    //发送一次ping包 ,不经过_outSeqQueue 直接存储在 out queue中<br>  { <br>   uint seq=this.getNextSequence(); <br>   MSG.CMPP_MSG_TEST test=new MSG.CMPP_MSG_TEST(seq); <br>   QueueItem q=new QueueItem(seq,(uint)MSG.CMPP_COMMAND_ID.CMPP_ACTIVE_TEST,0,0); <br>   q.setmsgObj(test); <br>   this.addToOutQueue(q);<br>  }<br>   <br>  private string getValIdTime(DateTime d)        //返回短信存活时间<br>  {<br>   DateTime n=d.AddHours(2); //2小时<br>   return(n.Year.ToString().Substring(2) + n.Month.ToString().PadLeft(2,<i>'</i>0<i>'</i>)+n.Day.ToString().PadLeft(2,<i>'</i>0<i>'</i>)+n.Hour.ToString().PadLeft(2,<i>'</i>0<i>'</i>)+n.Minute.ToString().PadLeft(2,<i>'</i>0<i>'</i>)+n.Second.ToString().PadLeft(2,<i>'</i>0<i>'</i>)+<i>"</i>032+<i>"</i>);            <br>  }<br> <br>  private bool isPingTime( )  //是否到了ping一次的时间<br>  {<br>   System.TimeSpan   l=(DateTime.Now - this._current_time );<br>   <br>   if ( l.TotalSeconds >= (CMPPClient.CMPP_ACTIVE_TEST_C_TICKs))<br>   {    <br>    lock(this)<br>    {<br>     this._current_time =DateTime.Now;        <br>     return(true);<br>    }<br>   }<br>   else<br>   {<br>    return(false);<br>   }<br>  }<br> <br>  private void checkReSend()    //是否需要再一次ping //查询 _waitingSeqQueue 是否存在 上一次 没有相应的消息<br>  {   //调查waiting queue 中的所有消息,如果入列时间超过60 <br>   for(int i=0;i<this._waitingSeqQueue.Count;i++)<br>   {<br>    Thread.Sleep(20); <br>    QueueItem q=(QueueItem)this._waitingSeqQueue.GetByIndex(i);   <br>    if(q!=null)<br>    {<br>     DateTime this_time=DateTime.Now  //去当前时间<br>     TimeSpan t=this_time-q.inQueueTime  <br>     if(t.TotalSeconds >CMPPClient.CMPP_ACTIVE_TEST_T_TICKs ) //达到超时时间<br>     {//需要重新发送消息<br>      if(q.FailedCount>=CMPPClient.CMPP_ACTIVE_TEST_N_COUNT)<br>      {<br>       //报告消息发送失败<br>       if(this.onWaitingItemDeltedHandler!=null)<br>       {<br>        WaitingQueueItemEventArgs e=new WaitingQueueItemEventArgs(q);<br>        this.onWaitingItemDeltedHandler(this,e); <br>       }<br>       this.delFromWaitingQueue(q); //从等待队列中删除 <br>       //q.MsgState =(int)MSG_STATE.SENDED_WAITTING; <br>      }<br>      else<br>      {//可以尝试继续发送<br>       q.inQueueTime = this_time;<br>       q.FailedCount ++ <br>       q.MsgState =(int)MSG_STATE.SENDED_WAITTING <br>       this.sendQueueItem(q);      <br>      }<br>     }      <br>    }<br>   }    <br>  <br>  }<br> <br>  private void startThreads()<br>  {<br>   Deamo_Thread=new Thread(new ThreadStart(this.DeamonThread));<br>   Deamo_Thread.Start(); <br>  }<br> <br>  private QueueItem newQueueItem(int msgtype,int msgstate,object msg)  //生成一个消息队列成员对象实例<br>  {<br>   uint seq=this.getNextSequence();   // <br>   QueueItem q=new QueueItem(seq,(uint)msgtype,0,msgstate);<br>   q.setmsgObj(msg);       //设定消息为 object<br>   return(q);<br>  }<br> <br>  private QueueItem getOutQueueItem(uint seq)  //获取MT 队列中的消息项目<br>  {<br>   lock(this)<br>   {<br>    return((QueueItem)this._outSeqQueue[seq])  <br>   }<br>  }<br> <br>  private QueueItem getWaitingQueueItem(uint seq)  //获取等待队列中的消息<br>  {<br>   return((QueueItem) this._waitingSeqQueue[seq]);<br>  }<br>        <br>  private void addToOutQueue(QueueItem q)<br>  {<br>   lock(this)<br>   {<br>    this._outSeqQueue.Add(q.Sequence,q);     <br>   }<br>  }<br> <br>  private void addToWaitingQueue(QueueItem q)<br>  {<br>   lock(this)<br>   {<br>    if(!this._waitingSeqQueue.ContainsKey(q.Sequence))<br>    {<br>     this._waitingSeqQueue.Add(q.Sequence,q);   <br>    }<br>   }<br>  }<br> <br>  private QueueItem getTopOutQueue()     //需要在取之前进行判断<br>  {<br>   for(int i=0;i<this._outSeqQueue.Count;i++)<br>   {<br>    QueueItem q=(QueueItem)this._outSeqQueue.GetByIndex(i);   <br>    if(q!=null)<br>    {<br>     if(q.MsgState==(int)MSG_STATE.NEW)  //新消息,立即返回<br>     {<br>      lock(this)<br>      {<br>       q.MsgState =(int)MSG_STATE.SENDING; //发送状态 <br>      }<br>      return(q);   <br>     }<br>     else<br>     {<br>      q=null;<br>     }<br>    }<br>   }    <br>   return(null);<br>  }<br> <br>  private ArrayList getTop16Queue() //返回16条最顶的消息<br>  {<br>   int arrlength=0;<br>   ArrayList reArr=new ArrayList() <br>   QueueItem q=getTopOutQueue();<br>   while(q!=null || arrlength <= 16)<br>   {    <br>    if(q!=null)<br>    {<br>     reArr.Add(q);<br>     arrlength++;<br>    }<br>    else<br>    {<br>     break;<br>    }<br>    q=getTopOutQueue();<br>   }<br>   <br>   if(arrlength>0)<br>   {<br>    return(reArr);   <br>   }<br>   else<br>   {<br>    return(null);<br>   }<br>  }<br> <br>  private void delFromOutQueue(QueueItem  q)<br>  {<br>   lock(this)<br>   {<br>    this._outSeqQueue.Remove(q.Sequence);   <br>   }<br>  }<br> <br>  private void delFromOutQueue(uint seq)<br>  {<br>   lock(this)<br>   {<br>    this._outSeqQueue.Remove(seq);  <br>   }<br>  }<br> <br>  private void delFromWaitingQueue(QueueItem q)<br>  {<br>   lock(this)<br>   {<br>    this._waitingSeqQueue.Remove(q.Sequence);  <br>   } <br>  }<br> <br>  private void delFromWaitingQueue(uint seq)<br>  {<br>   this._waitingSeqQueue.Remove(seq);  <br>  }<br> <br>  private void  SendLogin(string SystemID,string spNum,string Password) <br>  {//发送登录验证包    <br>   systemID=SystemID;<br>   userName=spNum;<br>   PassWord=Password; <br>   uint seq=this.getNextSequence(); //取得一个流水号 <br>   MSG.CMPP_MSG_CONNECT cn=new MSG.CMPP_MSG_CONNECT(seq);<br>   cn.Password =Password.Trim();<br>   cn.SourceAdd =SystemID.Trim();<br>   tcp.Send(cn.ToBytes()); <br>  }<br> <br><br>  private byte[]  prepairPKs(QueueItem outitem)//将QueueItem发送出去<br>  {<br>   uint seq=outitem.Sequence <br>   uint msgtype=outitem.MsgType;  <br>   switch(msgtype)<br>   {<br>    case (uint)MSG.CMPP_COMMAND_ID.CMPP_ACTIVE_TEST :<br>     MSG.CMPP_MSG_TEST test=(MSG.CMPP_MSG_TEST) outitem.getMsgObj(); //发送队列中取出<br>     lock(this)<br>     {<br>      outitem.MsgState =(int)MSG_STATE.SENDING;<br>      this.delFromOutQueue(seq);<br>      this.addToWaitingQueue(outitem);    //等待服务器的active_TEST_resp <br>     }<br>     outitem.MsgState =(int)MSG_STATE.SENDED_WAITTING <br>     return(test.toBytes());      <br>      <br> <br>    case (uint)MSG.CMPP_COMMAND_ID.CMPP_ACTIVE_TEST_RESP:<br>     MSG.CMPP_MSG_TEST_RESP test_reply=(MSG.CMPP_MSG_TEST_RESP)outitem.getMsgObj(); //发送队列中取出//取出需要发送的具体消息<br>     lock(this)<br>     {<br>      outitem.MsgState =(int)MSG_STATE.SENDING <br>      this.delFromOutQueue(seq);<br>     } <br>     outitem.MsgState = (int)MSG_STATE.SENDING_FINISHED   //完成<br>     return(test_reply.toBytes());<br>      <br>      <br> <br>    case (uint)MSG.CMPP_COMMAND_ID.CMPP_CANCEL :<br>     MSG.CMPP_MSG_CANCEL cancel=(MSG.CMPP_MSG_CANCEL)outitem.getMsgObj();    //还原成消息类<br>     lock(this)<br>     {<br>      outitem.MsgState =(int)MSG_STATE.SENDING <br>      this.delFromOutQueue(seq);<br>      this.addToWaitingQueue(outitem);    //等待回应<br>     }<br>     outitem.MsgState =(int)MSG_STATE.SENDED_WAITTING <br>     return(cancel.toBytes());      <br> <br>    case (uint)MSG.CMPP_COMMAND_ID.CMPP_DELIVER_RESP:<br>     MSG.CMPP_MSG_DELIVER_RESP deliver_resp=(MSG.CMPP_MSG_DELIVER_RESP)outitem.getMsgObj(); //发送队列中取出;<br>     lock(this)<br>     {<br>      outitem.MsgState =(int)MSG_STATE.SENDING <br>      this.delFromOutQueue(seq);<br>     }<br>     outitem.MsgState=(int)MSG_STATE.SENDING_FINISHED    //完成<br>     return (deliver_resp.toBytes());      <br>      <br> <br>    case (uint)MSG.CMPP_COMMAND_ID.CMPP_QUERY  :<br>     MSG.CMPP_MSG_QUERY query = (MSG.CMPP_MSG_QUERY )outitem.getMsgObj(); //发送队列中取出;<br>     lock(this)<br>     {<br>      outitem.MsgState =(int)MSG_STATE.SENDING  <br>      this.delFromOutQueue(seq);<br>      this.addToWaitingQueue(outitem); <br>     }<br>     outitem.MsgState =(int)MSG_STATE.SENDED_WAITTING  //等待回应<br>     return(query.toBytes());      <br>       <br>    case (uint)MSG.CMPP_COMMAND_ID.CMPP_SUBMIT :<br>     MSG.CMPP_MSG_SUBMIT submit =(MSG.CMPP_MSG_SUBMIT)outitem.getMsgObj(); //发送队列中取出;<br>     lock(this)<br>     {<br>      outitem.MsgState =(int)MSG_STATE.SENDING <br>      this.delFromOutQueue(seq);<br>      this.addToWaitingQueue (outitem); <br>     }<br>     outitem.MsgState =(int)MSG_STATE.SENDING_FINISHED <br>     return(submit.toBytes());<br>             <br>    case (uint)MSG.CMPP_COMMAND_ID.CMPP_TERMINATE :<br>     MSG.CMPP_MSG_TERMINATE terminate=(MSG.CMPP_MSG_TERMINATE)outitem.getMsgObj(); //发送队列中取出;<br>     lock(this)<br>     {<br>      outitem.MsgState =(int)MSG_STATE.SENDING <br>      this.delFromOutQueue(seq);<br>      this.addToWaitingQueue(outitem); <br>     }<br>     outitem.MsgState =(int)MSG_STATE.SENDED_WAITTING <br>     return(terminate.toBytes());      <br> <br>    case (uint)MSG.CMPP_COMMAND_ID.CMPP_TERMINATE_RESP :<br>     MSG.CMPP_MSG_TERMINATE_RESP terminate_resp=(MSG.CMPP_MSG_TERMINATE_RESP)outitem.getMsgObj(); //发送队列中取出;<br>     lock(this)<br>     {<br>      outitem.MsgState =(int)MSG_STATE.SENDING <br>      this.delFromOutQueue(seq);<br>     }<br>     outitem.MsgState =(int)MSG_STATE.SENDING_FINISHED   <br>     return(terminate_resp.toBytes()); <br><br>    default:   <br>     test=(MSG.CMPP_MSG_TEST) outitem.getMsgObj(); //发送队列中取出<br>     lock(this)<br>     {<br>      outitem.MsgState =(int)MSG_STATE.SENDING;<br>      this.delFromOutQueue(seq);<br>      this.addToWaitingQueue(outitem);    //等待服务器的active_TEST_resp <br>     }<br>     outitem.MsgState =(int)MSG_STATE.SENDED_WAITTING <br>     return(test.toBytes()); <br>   }    <br>  }<br><br>  private void sendQueueItem(QueueItem outitem)//将QueueItem发送出去<br>  {<br>   uint seq=outitem.Sequence <br>   uint msgtype=outitem.MsgType;<br>   try<br>   {<br>    switch(msgtype)<br>    { <br>     case (uint)MSG.CMPP_COMMAND_ID.CMPP_ACTIVE_TEST :<br>      MSG.CMPP_MSG_TEST test=(MSG.CMPP_MSG_TEST) outitem.getMsgObj(); //发送队列中取出<br>      lock(this)<br>      {<br>       outitem.MsgState =(int)MSG_STATE.SENDING;<br>       this.delFromOutQueue(seq);<br>       this.addToWaitingQueue(outitem);    //等待服务器的active_TEST_resp <br>      }<br>      tcp.Send(test.toBytes());<br>      outitem.MsgState =(int)MSG_STATE.SENDED_WAITTING <br>      break;<br> <br>     case (uint)MSG.CMPP_COMMAND_ID.CMPP_ACTIVE_TEST_RESP:<br>      MSG.CMPP_MSG_TEST_RESP test_reply=(MSG.CMPP_MSG_TEST_RESP)outitem.getMsgObj(); //发送队列中取出//取出需要发送的具体消息<br>      lock(this)<br>      {<br>       outitem.MsgState =(int)MSG_STATE.SENDING <br>       this.delFromOutQueue(seq);<br>      } <br>      tcp.Send(test_reply.toBytes());<br>      outitem.MsgState = (int)MSG_STATE.SENDING_FINISHED   //完成<br>      break;<br> <br>     case (uint)MSG.CMPP_COMMAND_ID.CMPP_CANCEL :<br>      MSG.CMPP_MSG_CANCEL cancel=(MSG.CMPP_MSG_CANCEL)outitem.getMsgObj();    //还原成消息类<br>      lock(this)<br>      {<br>       outitem.MsgState =(int)MSG_STATE.SENDING <br>       this.delFromOutQueue(seq);<br>       this.addToWaitingQueue(outitem);    //等待回应<br>      }<br>      tcp.Send(cancel.toBytes());      <br>      outitem.MsgState =(int)MSG_STATE.SENDED_WAITTING <br>      break; <br> <br>     case (uint)MSG.CMPP_COMMAND_ID.CMPP_DELIVER_RESP:<br>      MSG.CMPP_MSG_DELIVER_RESP deliver_resp=(MSG.CMPP_MSG_DELIVER_RESP)outitem.getMsgObj(); //发送队列中取出;<br>      lock(this)<br>      {<br>       outitem.MsgState =(int)MSG_STATE.SENDING <br>       this.delFromOutQueue(seq);<br>      }<br>      tcp.Send(deliver_resp.toBytes());<br>      outitem.MsgState=(int)MSG_STATE.SENDING_FINISHED    //完成<br>      break;<br> <br>     case (uint)MSG.CMPP_COMMAND_ID.CMPP_QUERY  :<br>      MSG.CMPP_MSG_QUERY query = (MSG.CMPP_MSG_QUERY )outitem.getMsgObj(); //发送队列中取出;<br>      lock(this)<br>      {<br>       outitem.MsgState =(int)MSG_STATE.SENDING  <br>       this.delFromOutQueue(seq);<br>       this.addToWaitingQueue(outitem); <br>      }<br>      tcp.Send(query.toBytes());<br>      outitem.MsgState =(int)MSG_STATE.SENDED_WAITTING  //等待回应<br>      break;<br> <br>     case (uint)MSG.CMPP_COMMAND_ID.CMPP_SUBMIT :<br>      MSG.CMPP_MSG_SUBMIT submit =(MSG.CMPP_MSG_SUBMIT)outitem.getMsgObj(); //发送队列中取出;<br>      lock(this)<br>      {<br>       outitem.MsgState =(int)MSG_STATE.SENDING <br>       this.delFromOutQueue(seq);<br>       this.addToWaitingQueue (outitem); <br>      }<br>      tcp.Send(submit.toBytes());<br>      outitem.MsgState =(int)MSG_STATE.SENDING_FINISHED <br>      break;<br> <br>     case (uint)MSG.CMPP_COMMAND_ID.CMPP_TERMINATE :<br>      MSG.CMPP_MSG_TERMINATE terminate=(MSG.CMPP_MSG_TERMINATE)outitem.getMsgObj(); //发送队列中取出;<br>      lock(this)<br>      {<br>       outitem.MsgState =(int)MSG_STATE.SENDING <br>       this.delFromOutQueue(seq);<br>       this.addToWaitingQueue(outitem); <br>      }<br>      if(this.tcpIsCanUse())<br>      {<br>       tcp.Send(terminate.toBytes());<br>       outitem.MsgState =(int)MSG_STATE.SENDED_WAITTING         <br>      }<br>      this.isStop =true;     //通知其他线程可以退出了 <br>      break;<br> <br>     case (uint)MSG.CMPP_COMMAND_ID.CMPP_TERMINATE_RESP :<br>      MSG.CMPP_MSG_TERMINATE_RESP terminate_resp=(MSG.CMPP_MSG_TERMINATE_RESP)outitem.getMsgObj(); //发送队列中取出;<br>      lock(this)<br>      {<br>       outitem.MsgState =(int)MSG_STATE.SENDING <br>       this.delFromOutQueue(seq);       <br>      }<br>      tcp.Send(terminate_resp.toBytes());<br>      outitem.MsgState =(int)MSG_STATE.SENDING_FINISHED        <br>      break;<br>    }<br>    LogLastOkTime(DateTime.Now );  //记录当前最后一次消息soket正确时间<br>   }<br>   catch(SocketException se)<br>   {<br>    //发生套接字错误<br>    this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+se.ToString ();<br>   }<br>   catch(NullReferenceException nre)<br>   {<br>    this._bNre =true;  //出现空引用错误<br>    this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+nre.ToString ();<br>   }<br>  }<br> <br>  private bool tcpIsCanUse()  //测试当前tcp是否可用<br>  {<br>   bool reval=true;<br>   DateTime t=DateTime.Now <br>   TimeSpan ts=t- this._lastOkTime;<br>   if(ts.TotalSeconds > CMPPClient.CMPP_ACTIVE_TEST_T_TICKs ) //60秒<br>   {<br>    reval=false;  //不可用<br>   }<br>   if(this._bNre )<br>   {<br>    reval=false;<br>   }<br>   return(reval);<br>  }<br> <br>  private void _reStartRecvNSend()<br>  {<br>   Send_Thread=new Thread(new ThreadStart(this.SendSPMsgThread)); <br>   Send_Thread.Start(); <br>   Recv_Thread=new Thread(new ThreadStart(this.RecvISMGMsgThread));<br>   Recv_Thread.Start();<br>  }<br> <br>  private void LogLastOkTime(DateTime lastoktime)<br>  {<br>   lock(this)<br>   {<br>    this._lastOkTime=lastoktime;  //设定最后成功消息交互时间 <br>   }<br>  }<br> <br>  private void defaultReportHandler() //却省的报告事件处理函数<br>  {<br> <br>  }<br> <br>  private void defaultSMSHandler()<br>  {<br> <br>  }<br> <br>  private void defaultTeminateHandler()<br>  {<br> <br>  }<br> <br>  private void defaultTestEventHandler()<br>  {<br> <br>  }<br>  private void defaultTestRespEventHandler()<br>  {<br> <br>  }<br>  private void defaultTerminateEventHandler()<br>  {<br>  }<br>  private void defaultTerminateRespEventHandler()<br>  {<br>  }<br>  private void defaultCancelRespEventHandler()<br>  {<br>  }<br>  private void defaultQueryRespEventHandler()<br>  {<br>  }<br> <br>  private void defaultConnectRespEventHandler()<br>  {<br>   QueueItem q=new QueueItem(this.getNextSequence(),(uint)MSG.CMPP_COMMAND_ID.CMPP_ACTIVE_TEST,0,(int)MSG_STATE.NEW);<br>   MSG.CMPP_MSG_TEST test=new MSG.CMPP_MSG_TEST(q.Sequence ); //立即发送包过去<br>   q.setmsgObj(test); <br>   this.addToOutQueue(q);   <br>  }<br>  private void defaultSubmitRespEventHandler()<br>  {<br>  }<br><br>  private void defaultClientStopEventHandler()<br>  {}<br>     <br>  private void rePortError(string info)<br>  {<br> <br>  }<br>        <br>  private bool _init(string CMPPServer,int CMPPPort)<br>  {<br>   bool reVal=false;<br>   CMPP_Server=CMPPServer;<br>   CMPP_Port=CMPPPort; <br>   try<br>   {<br>    tcp=new Socket(AddressFamily.InterNetwork ,SocketType.Stream ,ProtocolType.Tcp ); <br>    ip=Dns.GetHostByName(CMPP_Server); <br>    cmpp_ep=new IPEndPoint(ip.AddressList[0],CMPP_Port); <br>    tcp.Connect(cmpp_ep); //连接 <br>    reVal=true;   <br>   }<br>   catch(SocketException se)<br>   {<br>    ErrorInfo=<i>"</i>Socker Error:<i>"</i> + se.ToString();<br>   }<br>   return(reVal);   <br>  }<br>  private uint getNextSequence()<br>  {<br>   lock(typeof(CMPPClient))<br>   {<br>    try<br>    {<br>     lastSequence++;<br>    }<br>    catch(OverflowException ofe)<br>    {<br>     this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+ofe.ToString(); <br>     lastSequence=uint.Min<i>value</i>; <br>    }        <br>    return(lastSequence);<br>   }<br>  } <br> <br>  private void RecvISMGMsgThread()   //处理ISMG消息的线程<br>  {<br>   while(!this.isStop )<br>   {<br>    try<br>    {     <br>     byte[] rbuf=new byte[10240]; //结果缓冲区<br>     byte[] recv_temp=new Byte[1024]; //recv临时缓冲区<br>     int index=0;<br>     int msglength=tcp.Receive(rbuf);  //阻塞接收//分析收到的数据 <br> <br>     MSG.CMPP_MSG_Header header;  //=new MSG.CMPP_MSG_Header(rbuf,index); //取得一个消息                    <br>     while(index<msglength) //逐个消息分析<br>     {<br>      header=new MSG.CMPP_MSG_Header(rbuf,index); //取得一个消息       <br>      byte[] the_pk= new byte[header.MSGLength]    //生成此消息的大小<br>      for(int i=0;i<header.MSGLength i++)<br>      {<br>       the_pk<i>=rbuf[index++];<br>      }       <br>      uint seq; //取得回复消息的下一个流水序列号<br>      switch(header.Command_ID)<br>      {<br>       case (uint)MSG.CMPP_COMMAND_ID.CMPP_ACTIVE_TEST : //服务器给客户的测试信号<br>        this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+<i>"</i>收到:CMPP_ACTIVE_TEST<i>"</i>;<br>        MSG.CMPP_MSG_TEST test=new MSG.CMPP_MSG_TEST(the_pk);<br>        seq=test.Sequence;       //取得发送过来的流水号 <br>        MSG.CMPP_MSG_TEST_RESP test_reply=new MSG.CMPP_MSG_TEST_RESP(seq);   <br>        tcp.Send(test_reply.toBytes());    //马上送出回应包,不需要进入队列  <br>        if(this.onTestHandler!=null)<br>        {<br>         TestEventArgs e=new TestEventArgs(test);<br>         onTestHandler(this,e);<br>        }<br>        else<br>        {<br>         defaultTestEventHandler();<br>        }<br>        this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+<i>"</i>发送:CMPP_ACTIVE_TEST_RESP <i>"</i>; <br>        break;<br> <br>       case (uint)MSG.CMPP_COMMAND_ID.CMPP_ACTIVE_TEST_RESP : //服务器的回应消息,应当丢弃不管<br>        this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+(<i>"</i>收到:CMPP_ACTIVE_TEST_RESP <i>"</i>); <br>        MSG.CMPP_MSG_TEST_RESP test_reply2=new MSG.CMPP_MSG_TEST_RESP(the_pk); //构造消息<br>        seq=test_reply2.Sequence;    //寻找 曾经发送过去的消息         <br>        this.delFromWaitingQueue(seq);      //删除等待队列中的消息 //清空等待回应队列<br>        if(this.onTestRespHandler!=null)<br>        {<br>         TestRespEventArgs e=new TestRespEventArgs(test_reply2); <br>         onTestRespHandler(this,e);<br>        }<br>        else<br>        {<br>         defaultTestRespEventHandler();<br>        }<br>        break;<br> <br>       case (uint)MSG.CMPP_COMMAND_ID.CMPP_CANCEL_RESP :<br>        this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+(<i>"</i>收到:CMPP_CANCEL_RESP <i>"</i>); <br>        MSG.CMPP_MSG_CANCEL_RESP cancel_reply=new MSG.CMPP_MSG_CANCEL_RESP(the_pk);//构造消息<br>        seq=cancel_reply.Sequence;<br>        this.delFromWaitingQueue(seq);<br>        if(this.onCancelRespHandler!=null)<br>        {<br>         CancelRespEventArgs e=new CancelRespEventArgs(cancel_reply); <br>         onCancelRespHandler(this,e); <br>        }<br>        else<br>        {<br>         defaultCancelRespEventHandler();<br>        }<br>        break;<br> <br>       case (uint)MSG.CMPP_COMMAND_ID.CMPP_CONNECT_RESP :   //检查下消息的正确性,清除等待队列 设定连接成功标志<br>        this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+(<i>"</i>收到:CMPP_CONNECT_RESP <i>"</i>); <br>        MSG.CMPP_MSG_CONNECT_RESP cn_reply=new MSG.CMPP_MSG_CONNECT_RESP(the_pk);<br>        seq=cn_reply.Sequence;     //取得消息的seq<br>        if(this.onConnectRespHandler !=null)<br>        {<br>         ConnectRespEventArgs e=new ConnectRespEventArgs(cn_reply);<br>         onConnectRespHandler(this,e);<br>        }<br>        else<br>        {<br>         defaultConnectRespEventHandler();<br>        }<br>        if(cn_reply.isOk)<br>        {<br>         this.isLogin  =true;<br>        }<br>        else<br>        {<br>         this.isLogin  =false;<br>        }<br>        this.delFromWaitingQueue(seq);    //删除队列中的等待连接信息包 <br>        break;<br> <br>       case (uint)MSG.CMPP_COMMAND_ID.CMPP_DELIVER:    //检查消息正确定,立即返回 正确 或者 失败,正确则处理是否状态包,不是状态包则存到MO缓存,表示收到信息,时状态包则判断缓存消息进行消息送达处理<br>        this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+(<i>"</i>收到:CMPP_DELIVER <i>"</i>); <br>        BIConvert.DumpBytes(the_pk,<i>"</i>c:\\CMPP_DELIVER.txt<i>"</i>);//保留映像<br>        MSG.CMPP_MSG_DELIVER deliver=new MSG.CMPP_MSG_DELIVER(the_pk);        <br>        seq=(uint)deliver.ISMGSequence;       //发过来的流水号,需要立即发送一个deliver_resp       //一条 ISMG--〉SP 的消息<br>        MSG.CMPP_MSG_DELIVER_RESP deliver_resp=new MSG.CMPP_MSG_DELIVER_RESP(seq);       <br>        deliver_resp.MsgID =deliver.MsgID <br>        deliver_resp.Result =0;<br>        byte[] t=deliver_resp.toBytes();<br>        tcp.Send(t);<br>        this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+(<i>"</i>发送:CMPP__DELIVER_RESP <i>"</i>); <br>        if(deliver.isReport)<br>        {      //删除等待队列的消息//报告消息已经正确发送到        <br>         //UInt64 ReportMsgID=deliver.ReportMsgID  //取得消息ID ,更新 MsgID<br>         string StateReport=deliver.StateReport; //取得关于此消息的状态 <br>         //_debugBs(the_pk);<br>         ReportEventArgs arg=new ReportEventArgs(the_pk,MSG.CMPP_MSG_Header.HeaderLength+8+21+10+1+1+1+21+1+1);    //构造报告事件参数<br>         //ReportEventArgs arg=new ReportEventArgs(ReportMsgID.ToString(), <br>         if(this.onReportHandler!=null) //ReportEventArgs传递的字节数组是 报告信息包的数据,在此不考虑多个报告的情况<br>         {<br>          onReportHandler(this,arg);<br>         }<br>         else<br>         {<br>          this.defaultReportHandler();  <br>         }<br>        }<br>        else<br>        {//SMSEventArgs 传递的整个deliver包<br>         SMSEventArgs smsarg=new SMSEventArgs (the_pk,MSG.CMPP_MSG_Header.HeaderLength);  <br>         if(this.onSMSHandler!=null)<br>         {<br>          onSMSHandler(this,smsarg);   //触发事件,应当很快结束处理,不要靠考虑存储之类的耗费资源事宜<br>         }<br>         else<br>         {<br>          defaultSMSHandler();<br>         }<br>        }    <br>        break; <br> <br>       case (uint)MSG.CMPP_COMMAND_ID.CMPP_QUERY_RESP :<br>        this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+(<i>"</i>收到:CMPP_QUERY_RESP <i>"</i>); <br>        //收到消息,处理后存入数据库<br>        MSG.CMPP_MSG_QUERY_RESP query_resp=new MSG.CMPP_MSG_QUERY_RESP(the_pk);<br>        this.delFromWaitingQueue(query_resp.Sequence );   //将等待的队列中的元素删除<br>        if(this.onQueryRespHandler!=null)<br>        {<br>         QueryRespEventArgs e=new QueryRespEventArgs(query_resp); <br>        }<br>        else<br>        {<br>         defaultQueryRespEventHandler();<br>        }<br>        break;<br> <br>       case (uint)MSG.CMPP_COMMAND_ID.CMPP_SUBMIT_RESP :    //收到服务器送达的慧英消息<br>        this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+(<i>"</i>收到:CMPP_SUBMIT_RESP <i>"</i>);         <br>        MSG.CMPP_MSG_SUBMIT_RESP submit_resp=new MSG.CMPP_MSG_SUBMIT_RESP(the_pk);  <br>        BIConvert.DumpBytes(the_pk,<i>"</i>c:\\CMPP_SUBMIT_RESP.txt<i>"</i>);//保留映像<br>        //BIConvert.DumpBytes(init<i>value</i>,<i>"</i>c:\\CMPP_SUBMIT_RESP.txt<i>"</i>);//保留映像<br>        sub_resp++; //该变量仅供测试使用<br>        delFromWaitingQueue(submit_resp.Sequence);  //删除需要等待的消息<br>        if(this.onSubmitRespHandler!=null)<br>        {<br>         SubmitRespEventArgs e=new SubmitRespEventArgs(submit_resp);<br>         //submit_resp.<br>         onSubmitRespHandler(this,e);<br>        }<br>        else<br>        {<br>         defaultSubmitRespEventHandler();<br>        }<br> <br>        break;<br> <br>       case (uint)MSG.CMPP_COMMAND_ID.CMPP_TERMINATE :<br>        this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+<i>"</i>收到:CMPP_TERMINATE<i>"</i>;<br>        MSG.CMPP_MSG_TERMINATE terminate=new MSG.CMPP_MSG_TERMINATE(the_pk);<br>        seq=terminate.Sequence;<br>        MSG.CMPP_MSG_TERMINATE_RESP  terminate_resp=new MSG.CMPP_MSG_TERMINATE_RESP(seq);<br>        this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+<i>"</i>收到:CMPP_TERMINATE_RESP<i>"</i>;<br>        tcp.Send(terminate_resp.toBytes());  <br>        if(this.onTerminateHandler!=null)<br>        {<br>         TerminateEventArgs e=new TerminateEventArgs(terminate);<br>         onTerminateHandler(this,e);<br>         this.StopMe()  //准备自我停止?<br>        }<br>        else<br>        {<br>         defaultTerminateEventHandler();<br>        }<br>        this._StopMe();  //发出终止设定         <br>        return;   //退出线程        <br> <br>       case (uint)MSG.CMPP_COMMAND_ID.CMPP_TERMINATE_RESP :<br>        this.ErrorInfo =this.ErrorInfo +<i>"</i>\r\n<i>"</i>+<i>"</i>收到:CMPP_TERMINATE_RESP<i>"</i>;<br>        MSG.CMPP_MSG_TERMINATE_RESP ter_resp=new MSG.CMPP_MSG_TERMINATE_RESP(the_pk);<br>        seq=ter_resp.Sequence   //取得流水信号<br>        this.delFromOutQueue(seq);   //删除输出表重点项目 <br>        if(this.onTerminateRespHandler!=null)<br>        {<br>         TerminateRespEventArgs e=new TerminateRespEventArgs(ter_resp);<br>         onTerminateRespHandler(this,e);<br>        }<br>        else<br>        {<br>         defaultTerminateRespEventHandler();<br>        }<br>        this._StopMe(); <br>        break;<br>      }             <br>     }     <br>     LogLastOkTime(DateTime.Now );  //记录当前最后一次消息soket正确时间<br>    }<br>    catch(SocketException se)<br>    { <br>     //超时    <br>    }<br>    Thread.Sleep(50); <br>   }   <br>  }<br>  //debug<br>//  private void _debugBs(byte[] the_pk) //存储byte字节<br>//  {<br>//    <br>//  }<br>  //debug<br> <br>  private void DeamonThread()    //监视本系统连接是否正常<br>  {//此线程是监视线程<br>   int  t_count =0;   //循环时间计数<br>   _reStartRecvNSend();   //启动接收和发送<br>   while(! this.isStop) <br>   {      <br>    t_count++;    //0.1秒    <br>    if(tcpIsCanUse())  <br>    {<br>     if(this.isPingTime()) <br>     {<br>      this.ping();  //发送一个ping包 <br>     }<br>     if(t_count>50)  // 500*100=50000=50秒<br>     {<br>      t_count=0;<br>      checkReSend()  //检查需要重新发送的消息<br>      //触发一个事件,让系统自动检查消息队列,存储消息队列中的消息状态<br>     }<br>    }<br>    else<br>    {<br>     EventArgs e=new EventArgs(); <br>     if(this.onSocketClosedHandler!=null)<br>     {<br>      onSocketClosedHandler(this,e);<br>     }<br>     else<br>     {      <br>     }<br>     this.isStop =true;  //通知其他线程退出<br>    }<br>    Thread.Sleep(1000); <br>   }<br>  }   <br>  <br>  private void SendSPMsgThread()<br>  { <br>   while (!this.isStop )<br>   {<br>    Thread.Sleep(10); <br>    if(this.isLogin)<br>    {<br>     ArrayList lists=this.getTop16Queue();  //取出16条最顶的消息     <br>     if(lists!=null  && lists.Count >0)<br>     {<br>      int count=lists.Count;            <br>      ArrayList pks=new ArrayList( count); //定义容量<br>      for (int i=0;i<lists.Count; i++)<br>      {<br>       QueueItem outitem=(QueueItem)lists<i>; //取出每一个消息对象<br>       if(outitem!=null)<br>       {<br>        try<br>        {<br>         sendQueueItem(outitem);    //发送每一个消息<br>        }<br>        catch(SocketException se)<br>        {<br>         //发送失败<br>         outitem.FailedCount ++;<br>        }<br>       }      <br>      }<br>     }<br>    }<br>    Thread.Sleep(100); <br>   }  <br>  }  <br><br>  private void _StopMe()<br>  {<br>   lock(this)<br>   {<br>    this.isStop =true;<br>   }<br>  }<br> <br>  private void _forcedSubThread(Thread t)   //强制停止线程<br>  {<br>   try<br>   {<br>    t.Abort();<br>    t.Join();  <br>   }<br>   catch(Exception )<br>   {}<br>  }<br> <br>  //private 函数区域//////////////////////////////////////////////////////////////////<br> <br> <br>  //公用函数 属性区域//////////////////////////////////////// <br>  public bool Init(string CMPPServer,int CMPPPort)<br>  {<br>   return(this._init(CMPPServer,CMPPPort)); <br>  }<br> <br>  public bool Init(string CMPPServer,int 
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -