做家装模型的效果图网站,淮南王刘安,接网站 建设,怎么做不占CPU的网站这是2005年6月云南移动短信网关升级到3.0时写的#xff0c;在SP那稳定运行了很长时间的。因为SP倒闭了#xff0c;贴出来给有兴趣的朋友参考。优点#xff1a;支持多线程、滑动窗口、异步发送、全事件模式、自动识别ASCII、GBK、UCS-2缺点#xff1a;不支持长短信自动分页、…这是2005年6月云南移动短信网关升级到3.0时写的在SP那稳定运行了很长时间的。因为SP倒闭了贴出来给有兴趣的朋友参考。优点支持多线程、滑动窗口、异步发送、全事件模式、自动识别ASCII、GBK、UCS-2缺点不支持长短信自动分页、不支持PROVISION接口偶的PROVISION接口是用WEB SERVICE实现的
using System;using System.Text;using System.Runtime.InteropServices;using System.Threading;using System.Collections;using System.Diagnostics;using System.Net.Sockets;using System.Security.Cryptography;
namespace Tiray.SMS{ /// summary /// CMPP30 的摘要说明。 /// /summary public class CMPP30 { #region Constants public const Byte CMPP_VERSION_30 0x30; public const Byte CMPP_VERSION_21 0x20; public const UInt32 CMD_ERROR 0xFFFFFFFF; public const UInt32 CMD_CONNECT 0x00000001; public const UInt32 CMD_CONNECT_RESP 0x80000001; public const UInt32 CMD_TERMINATE 0x00000002; // 终止连接 public const UInt32 CMD_TERMINATE_RESP 0x80000002; // 终止连接应答 public const UInt32 CMD_SUBMIT 0x00000004; // 提交短信 public const UInt32 CMD_SUBMIT_RESP 0x80000004; // 提交短信应答 public const UInt32 CMD_DELIVER 0x00000005; // 短信下发 public const UInt32 CMD_DELIVER_RESP 0x80000005; // 下发短信应答 public const UInt32 CMD_QUERY 0x00000006; // 短信状态查询 public const UInt32 CMD_QUERY_RESP 0x80000006; // 短信状态查询应答 public const UInt32 CMD_CANCEL 0x00000007; // 删除短信 public const UInt32 CMD_CANCEL_RESP 0x80000007; // 删除短信应答 public const UInt32 CMD_ACTIVE_TEST 0x00000008; // 激活测试 public const UInt32 CMD_ACTIVE_TEST_RESP 0x80000008; // 激活测试应答 #endregion #region Protected Member Variables; protected string m_strSPID;//SP企业代码; protected string m_strPassword;//SP密码; protected string m_strAddress;//短信网关地址 protected int m_iPort;//短信网关端口号; protected static UInt32 m_iSeqID0;//命令的序号 protected int m_iSlidingWindowSize16;//滑动窗口大小(W) protected int m_iActiveTestSpan150;//ACTIVETEST的时间间隔(C,以秒为单位),标准为180 protected DateTime m_dtLastTransferTime;//最近一次网络传输时间 protected int m_iTimeOut60;//响应超时时间(T,以秒为单位) protected int m_iSendCount3;//最大发送次数(N) protected DATA_PACKAGE[] SlidingWindownull; protected TcpClient m_TcpClientnull; protected NetworkStream m_NetworkStreamnull; protected Queue m_MessageQueuenull;//消息队列用于保存所有待发送数据 protected int m_iTcpClientTimeout5;//TcpClient接收和发送超时以秒为单位 protected int m_iSendSpan10;//发送间隔以毫秒为单位 #endregion #region Worker Thread protected System.Threading.Thread m_SendThreadnull; protected System.Threading.Thread m_ReceiveThreadnull; protected AutoResetEvent m_eventSendExitnew AutoResetEvent(false); protected AutoResetEvent m_eventReceiveExitnew AutoResetEvent(false); protected AutoResetEvent m_eventConnectnew AutoResetEvent(false); protected AutoResetEvent m_eventDisconnectnew AutoResetEvent(false); protected ManualResetEvent m_eventSendnew ManualResetEvent(false); protected ManualResetEvent m_eventReceivenew ManualResetEvent(false); protected void SendThreadProc() { while(true) { if(m_eventSendExit.WaitOne(TimeSpan.FromMilliseconds(0),false)) { Disconnect(); break; } if(m_eventConnect.WaitOne(TimeSpan.FromMilliseconds(0),false))//连接 { if(Connect())//连接上开始发送和接收 { m_eventSend.Set(); m_eventReceive.Set(); } else { Close(); Thread.Sleep(5000); m_eventConnect.Set(); } } if(m_eventDisconnect.WaitOne(TimeSpan.FromMilliseconds(0),false))//拆除连接 { m_eventSend.Reset(); m_eventReceive.Reset(); Disconnect(); Thread.Sleep(5000); m_eventConnect.Set(); } if((m_eventSend.WaitOne(TimeSpan.FromMilliseconds(0),false))(m_NetworkStream!null)) { bool bOKtrue; ActiveTest(); Monitor.Enter(SlidingWindow); for(int i0;im_iSlidingWindowSize;i)//首先用消息队列中的数据填充滑动窗口 { if(SlidingWindow[i].Status0) { DATA_PACKAGE dpnew DATA_PACKAGE(); dp.Datanull; Monitor.Enter(m_MessageQueue); if(m_MessageQueue.Count0) { dp (DATA_PACKAGE)m_MessageQueue.Dequeue(); SlidingWindow[i]dp; } Monitor.Exit(m_MessageQueue); } } for(int i0;im_iSlidingWindowSize;i) { DATA_PACKAGE dp SlidingWindow[i]; if((dp.Status1)(dp.SendCount0))//第一次发送 { bOKSend(dp); if((bOK)(dp.Command0x80000000))//发送的是Response类的消息不需等待Response { SlidingWindow[i].Status0;//清空窗口 } else if((bOK)(dp.Command0x80000000))//发送的是需要等待Response的消息 { SlidingWindow[i].SendTimeDateTime.Now; SlidingWindow[i].SendCount; } else { bOKfalse; break;//网络出错 } } else if((dp.Status1)(dp.SendCount0))//第N次发送 { if(dp.SendCountm_iSendCount-1)//已发送m_iSendCount次,丢弃数据包 { SlidingWindow[i].Status0;//清空窗口 if(dp.CommandCMPP30.CMD_ACTIVE_TEST)//是ActiveTest { bOKfalse; break;//ActiveTest出错 } } else { TimeSpan tsDateTime.Now-dp.SendTime; if(ts.TotalSecondsm_iTimeOut)//超时后未收到回应包 { bOKSend(dp);//再次发送 if(bOK) { SlidingWindow[i].SendTimeDateTime.Now; SlidingWindow[i].SendCount; } else { bOKfalse; break;//网络出错 } } } } } Monitor.Exit(SlidingWindow); if(!bOK) { Close();//关闭连接 Thread.Sleep(5000);//等待5秒 m_eventSend.Reset(); m_eventConnect.Set(); } } } } protected void ReceiveThreadProc() { while(true) { if(m_eventReceiveExit.WaitOne(TimeSpan.FromMilliseconds(0),false)) { break; } if((m_eventReceive.WaitOne(TimeSpan.FromMilliseconds(0),false)(m_NetworkStream!null))) { CMPP_HEAD HeadReadHead(); if(Head.CommandIDCMPP30.CMD_SUBMIT_RESP) { ReadSubmitResp(Head); } else if(Head.CommandIDCMPP30.CMD_ACTIVE_TEST) { ActiveTestResponse(Head.SequenceID); } else if(Head.CommandIDCMPP30.CMD_ACTIVE_TEST_RESP) { ReadActiveTestResponse(Head); } else if(Head.CommandIDCMPP30.CMD_DELIVER) { ReadDeliver(Head); } else if(Head.CommandIDCMPP30.CMD_ERROR)//网络故障 { m_eventReceive.Reset(); m_eventDisconnect.Set(); } } } } #endregion #region Constructor public CMPP30(string SPID,string Password,string Address,int Port) { m_strSPIDSPID; m_strPasswordPassword; m_strAddressAddress; m_iPortPort; SlidingWindownew DATA_PACKAGE[m_iSlidingWindowSize];//初始化滑动窗口 for(int i0;im_iSlidingWindowSize;i) SlidingWindow[i]new DATA_PACKAGE(); m_MessageQueuenew Queue(); } #endregion #region SMSEvents public event Tiray.SMS.SMSEventHandler SMSStateChanged; protected void RaiseEvent(SMS_STATE State,Object Data) { if(null!SMSStateChanged) { SMSEventArgs enew SMSEventArgs(); e.TimeDateTime.Now; e.StateState; e.DataData; SMSStateChanged(this,e); } } #endregion #region Protected Methods protected UInt32 TimeStamp(DateTime dt) { string strString.Format({0:MMddhhmmss},dt); return Convert.ToUInt32(str); } protected UInt32 CreateID() { UInt32 idm_iSeqID; m_iSeqID; if(m_iSeqIDUInt32.MaxValue) m_iSeqID0; return id; } protected Byte[] CreateDigest(DateTime dt) { int iLength25m_strPassword.Length; Byte[] btContentnew Byte[iLength]; Array.Clear(btContent,0,iLength); int iPos0; foreach(char ch in m_strSPID) { btContent[iPos](Byte)ch; iPos; } iPos9; foreach(char ch in m_strPassword) { btContent[iPos](Byte)ch; iPos; } string strTimeStampString.Format({0:MMddhhmmss},dt); foreach(char ch in strTimeStamp) { btContent[iPos](Byte)ch; iPos; } MD5 md5 new MD5CryptoServiceProvider(); return md5.ComputeHash(btContent); } protected bool Close() { if(m_NetworkStream!null) m_NetworkStream.Close(); if(m_TcpClient!null) m_TcpClient.Close(); m_TcpClientnull; m_NetworkStreamnull; return true; } protected bool Connect() { bool bOKtrue; string strErrorstring.Empty; CMPP_CONNECT_RESP respnew CMPP_CONNECT_RESP(); try { m_TcpClientnew TcpClient(); m_TcpClient.ReceiveTimeoutm_TcpClient.SendTimeoutm_iTcpClientTimeout*1000; m_TcpClient.Connect(m_strAddress,m_iPort); m_NetworkStreamm_TcpClient.GetStream(); DateTime dtDateTime.Now; CMPP_CONNECT connnew CMPP_CONNECT(); conn.Headnew CMPP_HEAD(); conn.Head.CommandIDCMPP30.CMD_CONNECT; conn.Head.SequenceIDCreateID(); conn.SourceAddressm_strSPID; conn.TimeStampTimeStamp(dt); conn.AuthenticatorSourceCreateDigest(dt); conn.VersionCMPP_VERSION_30; Byte[] bufferconn.GetBuffer(); m_NetworkStream.Write(buffer,0,(Int32)conn.Head.TotalLength); int iSpan0; bool bTimeOutfalse; while(!m_NetworkStream.DataAvailable)//等待RESPONSE 5秒 { Thread.Sleep(10); iSpan; if(iSpan500) { bTimeOuttrue; break; } } if(!bTimeOut) { CMPP_HEAD HeadReadHead(); if(Head.CommandIDCMD_CONNECT_RESP) { respReadConnectResp(Head); if(resp.Status0) bOKtrue; else { bOKfalse; strError未正确接收CONNECT_RESP; } } } else { bOKfalse; strError等待CONNECT_RESP超时; } } catch(Exception e) { strErrore.Message; bOKfalse; } if(bOK) RaiseEvent(SMS_STATE.SP_CONNECT,resp); else RaiseEvent(SMS_STATE.SP_CONNECT_ERROR,strError); return bOK; } protected bool Disconnect() { bool bOKtrue; string strErrorstring.Empty; try { DateTime dtDateTime.Now; CMPP_HEAD Headnew CMPP_HEAD(); Head.CommandIDCMPP30.CMD_TERMINATE; Head.SequenceIDCreateID(); Head.TotalLength(UInt32)Marshal.SizeOf(Head); Byte[] bufferHead.GetBuffer(); m_NetworkStream.Write(buffer,0,(Int32)Head.TotalLength); int iSpan0; bool bTimeOutfalse; while(!m_NetworkStream.DataAvailable)//等待RESPONSE 5秒 { Thread.Sleep(10); iSpan; if(iSpan500) { bTimeOuttrue; break; } } if(!bTimeOut) { HeadReadHead(); if(Head.CommandIDCMD_TERMINATE_RESP) bOKtrue; else { bOKfalse; strError未正确接收TERMINATE_RESP; } } else { bOKfalse; strError等待TERMINATE_RESP超时; } } catch (Exception ex) { bOKfalse; strErrorex.Message; } if(m_NetworkStream!null) m_NetworkStream.Close(); if(m_TcpClient!null) m_TcpClient.Close(); m_TcpClientnull; m_NetworkStreamnull; if(bOK) RaiseEvent(SMS_STATE.SP_DISCONNECT,null); else RaiseEvent(SMS_STATE.SP_DISCONNECT_ERROR,strError); return bOK; } protected bool Send(DATA_PACKAGE dp) { bool bOKtrue; string strErrorstring.Empty; SMS_STATE stateSMS_STATE.UNKNOW_ERROR; try { Thread.Sleep(m_iSendSpan); Byte[] btDatanull; if(dp.CommandCMD_ACTIVE_TEST) { btData((CMPP_HEAD)dp.Data).GetBuffer(); stateSMS_STATE.ACTIVE_TEST; } else if(dp.CommandCMD_ACTIVE_TEST_RESP) { btData((CMPP_ACTIVE_TEST_RESP)dp.Data).GetBuffer(); stateSMS_STATE.ACTIVE_TEST_RESPONSE; } else if(dp.CommandCMD_DELIVER_RESP) { btData((CMPP_DELIVER_RESP)dp.Data).GetBuffer(); stateSMS_STATE.DELIVER_RESPONSE; } else if(dp.CommandCMD_SUBMIT) { btData((CMPP_SUBMIT)dp.Data).GetBuffer(); stateSMS_STATE.SUBMIT; } m_NetworkStream.Write(btData,0,btData.Length); m_dtLastTransferTimeDateTime.Now; } catch(Exception ex) { bOKfalse; strErrorex.Message; } if(bOK) { RaiseEvent(state,dp.Data); } else { if(stateSMS_STATE.ACTIVE_TEST) stateSMS_STATE.ACTIVE_TEST_ERROR; else if(stateSMS_STATE.ACTIVE_TEST_RESPONSE) stateSMS_STATE.ACTIVE_TEST_RESPONSE_ERROR; else if(stateSMS_STATE.DELIVER_RESPONSE) stateSMS_STATE.DELIVER_RESPONSE_ERROR; else if(stateSMS_STATE.SUBMIT) stateSMS_STATE.SUBMIT_ERROR; RaiseEvent(state,strError); } return bOK; }