⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmpp.cs

📁 用于移动梦网网关进行TCP通信,可以收发短信,并实现计费功能.使用SOCKET实现,并具有收发读写保护功能.可作为TCP通信和线程读写同步的教程.
💻 CS
📖 第 1 页 / 共 5 页
字号:
			{
				return this.mymsg;
			}
			set
			{
				this.mymsg=value;
				this.hasmymsg=true;
			}
		}
		public bool HasMyMessage
		{
			get
			{
				return this.hasmymsg;
			}
		}
		public string ErrorMessage
		{
			get
			{
				return this.errormsg;
			}
			set
			{
				this.errormsg=value;
			}
		}
	}
	#endregion
	/// <summary>
	/// 本类实现CMPP3.0协议的各项功能
	/// </summary>
	public class CMPP3Client:System.IDisposable
	{
		//*********************************************************************************
		//                       私有成员定义
		//*********************************************************************************
		//                      1数据定义
		/// <summary>
		/// 握手消息发送频率,30s一次
		/// </summary>
		private const int CMPP_ActiveTestTime_C=30;
		/// <summary>
		/// 消息发送最大次数,3次
		/// </summary>
		private const int CMPP_MaxFailTimes_N=0;
		/// <summary>
		/// 最长等待应答时间60s
		/// </summary>
		private const int CMPP_MaxWaitRespTime_T=120;
		private uint LastSequence=0;//全局使用一个流水号,初始化为0
		private DateTime LastTcpUseTime=DateTime.Now;
		private CMPPState State;//系统当前状态
		private SortedList OutQueue=new SortedList();//待发送队列
		private SortedList WaitQueue=new SortedList();//已发送队列
		private bool isLogin=false;
		private bool IfCanProc=false;
		private ReaderWriterLock RWL_IfCanProce=new ReaderWriterLock();
		private bool IfCanAddItemToOutQueue=false;
		private ReaderWriterLock RWL_IfCanAddItemToOutQueue=new ReaderWriterLock();
		private bool IfCanRecvItemFromOutQueue=false;
		private ReaderWriterLock RWL_IfCanRecvItemFromOutQueue=new ReaderWriterLock();
		private byte[] LastBytes=new byte[0];
		private ReaderWriterLock RWL_LastBytes=new ReaderWriterLock();
		private DateTime LastRecvISMGTime=DateTime.Now;
		private DateTime LastSentISMGTime=DateTime.Now;
		private ReaderWriterLock RWL_LastRecvISMGTime=new ReaderWriterLock();
		private ReaderWriterLock RWL_LastSentISMGTime=new ReaderWriterLock();
		private int RecvNullNum=0;
		//*********************************************************************************
		//                      2登陆定义
		/// <summary>
		/// SPID
		/// </summary>
		private string SPID;
		/// <summary>
		/// 登陆时的用户名
		/// </summary>
		private string UserName;
		/// <summary>
		/// 登陆密码
		/// </summary>
		private string Password;
		/// <summary>
		/// 特服号
		/// </summary>
		private string SpecialCode;
		//*********************************************************************************
		//						3事件定义
		#region 事件定义
		public event CMPP3.Client.RequestRestartEventHandler onRequestRestartHandler;
		/// <summary>
		/// 接收到状态报告
		/// </summary>
		public event RecvReportEventHandler onReceiveReportHandler;
		/// <summary>
		/// 接收到新短消息
		/// </summary>
		public event RecvSMSEnventHandler onReceiveNewShortMessageHandler;
		/// <summary>
		/// 接收到服务器端发来的请求拆除连接
		/// </summary>
		public event RecvTerminateEventHandler onReceiveTerminateHandler;
		/// <summary>
		/// 接收到服务器发来的对本机请求拆除连接的回应
		/// </summary>
		public event RecvTerminateRespEventHandler onReceiveTerminateRespHandler;
		/// <summary>
		/// 当本机发送了请求断开连接时发生
		/// </summary>
		public event SentTerminateEventHandler onSentTerminateHander;
		/// <summary>
		/// 当本机回应了网关的请求拆除连接是发生
		/// </summary>
		public event SentTerminateRespEventHandler onSentTerminateRespHandler;
		/// <summary>
		/// 当发送了握手消息时发生
		/// </summary>
		public event SentTestEventHandler onSentTestHandler;
		/// <summary>
		/// 当接收到握手消息回应时发生
		/// </summary>
		public event RecvTestRespEventHandler onReceiveTestRespHandler;
		/// <summary>
		/// 当接收到握手信息时发生
		/// </summary>
		public event RecvTestEventHandler onReceiveTestHandler;
		/// <summary>
		/// 当发送了握手信息的回复是发生
		/// </summary>
		public event SentTestRespEventHandler onSentTestRespHandler;
		/// <summary>
		/// 当接收到登陆信息的回复时发生
		/// </summary>
		public event RecvConnectRespEventHandler onReceiveConnectRespHandler;
		/// <summary>
		/// 当发送了登陆信息后发生
		/// </summary>
		public event SentConnectEventHandler onSentConnectHandler;
		/// <summary>
		/// 当发送取消发送信息时发生
		/// </summary>
		public event SentCancelEventHandler onSentCancelHandler;
		/// <summary>
		/// 当接收到取消发送信息时发生
		/// </summary>
		public event RecvCancelRespEventHandler onReceiveCancelRespHandler;
		/// <summary>
		/// 当接收到发送消息的回复时发生
		/// </summary>
		public event RecvSubmitRespEventHandler onReceiveSubmitRespHandler;
		/// <summary>
		/// 当发送了Submit消息时发生
		/// </summary>
		public event SentSubmitEventHandler onSentSubmitHandler;
		/// <summary>
		/// 当接收到查询信息的回复时发生
		/// </summary>
		public event RecvQueryRespEventHandler onReceiveQueryRespHandler;
		/// <summary>
		/// 当发送了查询信息时发送
		/// </summary>
		public event SentQueryEventHandler onSentQueryHandler;
		/// <summary>
		/// 当登陆成功时发送
		/// </summary>
		public event LoginSuccEventHandler onLoginSuccessHandler;
		/// <summary>
		/// 当套接字连接异常时发生
		/// </summary>
		public event SocketClosedEventHandler onSocketCloseHandler;
		/// <summary>
		/// 当信息发送超次数时发生
		/// </summary>
		public event FailedItemDeletedEventHandler onFailedItemDeletedHandler;
		/// <summary>
		/// 当系统出现错误或出现某些信息时发生
		/// </summary>
		public event ErrorEventHandler onErrorHandler;
		#endregion
		//*********************************************************************************
		//						4套接字定义
		private IPAddress GWIP;
		private int SendPort;
		private IPEndPoint ServerIPEP;
		private Socket SeverSocket;//使用此SOCKET与网关进行通信
		private ReaderWriterLock RWL_ServerSocket;
		private System.Messaging.MessageQueue MSMQ_CMPP3GateWayService_OutQueue;
		private System.Threading.ReaderWriterLock RWL_OutQueue=new ReaderWriterLock();
		private System.Messaging.MessageQueue MSMQ_CMPP3GateWayService_TempQueue;
		private System.Threading.ReaderWriterLock RWL_TempQueue=new ReaderWriterLock();
		//********************************************************************************
		//						5线程定义
		private Thread thDeamon;
		private Thread thSendMsg;
		private Thread thRecvMsg;
		private ReaderWriterLock RWL_Sequence=new ReaderWriterLock();//定义一个对流水号的读写保护锁
		//private ReaderWriterLock RWL_OutQueue=new ReaderWriterLock();//定义一个对待发送队列的读写保护锁
		private ReaderWriterLock RWL_WaitQueue=new ReaderWriterLock();//定义一个对已发送队列的读写保护锁
		private ReaderWriterLock RWL_LastTcpTime=new ReaderWriterLock();//定义一个对TCP使用记录的读写保护锁
		//*********************************************************************************
		public CMPP3Client(string LoginSPID,string LoginUserName,string LoginPassWord,IPAddress ServerIP,int ServerPort,string ServiceCode)
		{
			this.SPID=LoginSPID;
			this.UserName=LoginUserName;
			this.Password=LoginPassWord;
			this.GWIP=ServerIP;
			this.SendPort=ServerPort;
			this.ServerIPEP=new IPEndPoint(this.GWIP,this.SendPort);
			this.SeverSocket=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
			this.SpecialCode=ServiceCode;
			this.RWL_ServerSocket=new ReaderWriterLock();
			string outqueuepath=@".\Private$\CMPP3GateWay_OutQueue";
			if(!System.Messaging.MessageQueue.Exists(outqueuepath))
			{
				System.Messaging.MessageQueue.Create(outqueuepath);
			}
			string tempqueuepath=@".\Private$\CMPP3GateWay_TempQueue";
			if(!System.Messaging.MessageQueue.Exists(tempqueuepath))
			{
				System.Messaging.MessageQueue.Create(tempqueuepath);
			}
			this.MSMQ_CMPP3GateWayService_OutQueue=new System.Messaging.MessageQueue(outqueuepath,false);
			this.MSMQ_CMPP3GateWayService_OutQueue.Formatter=new System.Messaging.BinaryMessageFormatter(System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Full, System.Runtime.Serialization.Formatters.FormatterTypeStyle.TypesAlways);
			this.MSMQ_CMPP3GateWayService_OutQueue.ReceiveCompleted+=new System.Messaging.ReceiveCompletedEventHandler(MSMQ_CMPP3GateWayService_OutQueue_ReceiveCompleted);
			this.MSMQ_CMPP3GateWayService_TempQueue=new System.Messaging.MessageQueue(tempqueuepath,false);
			this.MSMQ_CMPP3GateWayService_TempQueue.Formatter=new System.Messaging.BinaryMessageFormatter(System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Full, System.Runtime.Serialization.Formatters.FormatterTypeStyle.TypesAlways);
		}
		#region IDisposable 成员

		public void Dispose()
		{
			
			try
			{
				this.SeverSocket.Close();
			}
			catch
			{}
			try
			{
				this.thDeamon.Abort();
			}
			catch
			{}
			try
			{
				this.RWL_LastTcpTime.ReleaseLock();
			}
			catch
			{}
			try
			{
				this.RWL_OutQueue.ReleaseLock();
			}
			catch
			{}
			try
			{
				this.RWL_Sequence.ReleaseLock();
			}
			catch
			{}
			try
			{
				this.RWL_ServerSocket.ReleaseLock();
			}
			catch
			{}
			try
			{
				this.RWL_TempQueue.ReleaseLock();
			}
			catch
			{}
			try
			{
				this.RWL_WaitQueue.ReleaseLock();
			}
			catch
			{}
			try
			{
				this.MSMQ_CMPP3GateWayService_OutQueue.Close();
			}
			catch
			{}
			try
			{
				this.MSMQ_CMPP3GateWayService_OutQueue.Dispose();
			}
			catch
			{}
			try
			{
				this.MSMQ_CMPP3GateWayService_TempQueue.Close();
			}
			catch
			{}
			try
			{
				this.MSMQ_CMPP3GateWayService_TempQueue.Dispose();
			}
			catch
			{}
		}

		#endregion
		//**************************************************************************************
		//						公有函数
		/// <summary>
		/// 发送短消息
		/// </summary>
		/// <param name="DestTermID">接收此消息的用户</param>
		/// <param name="DestTerminalType">接收用户号码类型</param>
		/// <param name="Fee">短信费率</param>
		/// <param name="FeeTerminalID">被计费用户号码</param>
		/// <param name="FeeTerminalType">被计费用户号码类型</param>
		/// <param name="FeeType">资费类别</param>
		/// <param name="FeeUserType">被计费用户用户类型</param>
		/// <param name="IfNeedReoport">是否返回状态报告</param>
		/// <param name="LinkID"></param>
		/// <param name="MsgFmt"></param>
		/// <param name="ServiceCode">计费代码</param>
		/// <param name="LongCode">长号码</param>
		/// <param name="Tp_Pid"></param>
		/// <param name="Tp_Udhi"></param>
		public bool SubmitSM(MtMessageForMISC mmfm)
		{
			switch(mmfm.MessageType)
			{
				case 0:
				{
					//ASCII码
					byte[] bsmsg=Convert.FromBase64String(mmfm.MessageContent);
					int quantity=bsmsg.Length/160+1;
					for(int i=0;i<quantity;i++)
					{
						uint seq=this.getNextSequence();
						MSG.CMPP_Submit submit=new CMPP3.Client.MSG.CMPP_Submit(seq);
						submit.AtTime="";
						submit.AddDestID(mmfm.DestMsisdn);
						submit.DestTermType=0;
						if(i==0)
						{
							
							submit.FeeCode=mmfm.Fee.ToString().PadLeft(6,'0');
							submit.LinkID=mmfm.MOMessageID;
						}
						else
						{
							submit.FeeType="01";
							submit.Service_ID="BZXX";
							submit.LinkID="";
							submit.FeeCode="000000";
						}
						submit.FeeTerminalID=mmfm.FeeMsisdn;
						submit.FeeTerminalType=0;
						submit.FeeType=mmfm.FeeType.ToString().PadLeft(2,'0');
						submit.FeeUserType=(byte)mmfm.FeeUserType;
						submit.ifNeedReport=(byte)mmfm.NeedReport;
						//submit.LinkID=mmfm.MOMessageID;
//						submit.PK_Total=(byte)quantity;
//						submit.PK_Num=(byte)i;
						if(i<quantity-1)
						{
							byte[] _bsmsg=new byte[160];
							Array.Copy(bsmsg,i*160,_bsmsg,0,160);
							submit.SetMsgContent(_bsmsg,0);
						}
						else
						{
							int size=bsmsg.Length-i*160;
							byte[] _bsmsg=new byte[size];
							Array.Copy(bsmsg,i*160,_bsmsg,0,size);
							submit.SetMsgContent(_bsmsg,0);
						}
						submit.MsgLevel=3;
						submit.MsgSrc=this.SPID;
						submit.Service_ID=mmfm.FeeCode;
						submit.Src_Id=this.SpecialCode+mmfm.LongCode;
						if(submit.Src_Id.Length>21)
						{
							//如果长号码信息长度大于21位则只提取21位
							submit.Src_Id=submit.Src_Id.Substring(0,21);
						}
						submit.TpPid=(byte)mmfm.TP_Pid;
						submit.TpUdhi=(byte)mmfm.TP_Udhi;
						submit.ValId_Time="";
						submit.SMBPMtMessage=mmfm;
						QueueItem q=new QueueItem();//(seq,(uint)MSG.CMPP_COMMAND_ID.CMPP_SUBMIT,0,0,submit);
						q.FailTimes=0;
						q.InQueueTime=DateTime.Now;
						q.Msg=submit;
						q.MsgSequence=seq;
						q.MsgType=(uint)MSG.CMPP_COMMAND_ID.CMPP_SUBMIT;
						if(this.GetIfCanAddItemToOutQueue())
						{
							this.AddItemToOutQueueToGateWay(q);
						}
						else
						{
							this.AddQueueItemToBufferQueue(q);
						}
					}
					return true;
				}
				case 8:
				{
					//USC2--Unicode编码
					byte[] bsmsg=Convert.FromBase64String(mmfm.MessageContent);
					string str=System.Text.Encoding.Unicode.GetString(bsmsg);
					bsmsg=System.Text.Encoding.BigEndianUnicode.GetBytes(str);
					int quantity=bsmsg.Length/140+1;
					for(int i=0;i<quantity;i++)
					{
						uint seq=this.getNextSequence();
						MSG.CMPP_Submit submit=new CMPP3.Client.MSG.CMPP_Submit(seq);
						submit.AtTime="";
						submit.AddDestID(mmfm.DestMsisdn);
						submit.DestTermType=0;
						if(i==0)
						{
							submit.FeeCode=mmfm.Fee.ToString().PadLeft(6,'0');
							submit.LinkID=mmfm.MOMessageID;
						}
						else
						{
							submit.FeeType="01";
							submit.Service_ID="BZXX";
							submit.LinkID="";
							submit.FeeCode="000000";
						}
						submit.FeeTerminalID=mmfm.FeeMsisdn;
						submit.FeeTerminalType=0;
						submit.FeeType=mmfm.FeeType.ToString().PadLeft(2,'0');
						submit.FeeUserType=(byte)mmfm.FeeUserType;
						submit.ifNeedReport=(byte)mmfm.NeedReport;
						//submit.LinkID=mmfm.MOMessageID;
//						submit.PK_Total=(byte)quantity;
//						submit.PK_Num=(byte)i;
						if(i<quantity-1)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -