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

📄 cmpp.cs

📁 用于移动梦网网关进行TCP通信,可以收发短信,并实现计费功能.使用SOCKET实现,并具有收发读写保护功能.可作为TCP通信和线程读写同步的教程.
💻 CS
📖 第 1 页 / 共 5 页
字号:
						{
							byte[] _bsmsg=new byte[140];
							Array.Copy(bsmsg,i*140,_bsmsg,0,140);
							submit.SetMsgContent(_bsmsg,8);
						}
						else
						{
							int size=bsmsg.Length-i*140;
							byte[] _bsmsg=new byte[size];
							Array.Copy(bsmsg,i*140,_bsmsg,0,size);
							submit.SetMsgContent(_bsmsg,8);
						}
						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 15:
				{
					//GB2312编码
					byte[] bsmsg=Convert.FromBase64String(mmfm.MessageContent);
					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;
//						submit.PK_Total=(byte)quantity;
//						submit.PK_Num=(byte)i;
						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;
						
						if(i<quantity-1)
						{
							byte[] _bsmsg=new byte[140];
							Array.Copy(bsmsg,i*140,_bsmsg,0,140);
							submit.SetMsgContent(_bsmsg,15);
						}
						else
						{
							int size=bsmsg.Length-i*140;
							byte[] _bsmsg=new byte[size];
							Array.Copy(bsmsg,i*140,_bsmsg,0,size);
							submit.SetMsgContent(_bsmsg,15);
						}
						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;
				}
				default:
				{
					//其他都以2进制下发
					byte[] bsmsg=Convert.FromBase64String(mmfm.MessageContent);
					if(bsmsg.Length>140)
					{
						return false;
					}
					
					uint seq=this.getNextSequence();
					MSG.CMPP_Submit submit=new CMPP3.Client.MSG.CMPP_Submit(seq);
					submit.AtTime="";
					submit.AddDestID(mmfm.DestMsisdn);
					submit.DestTermType=0;
					submit.FeeCode=mmfm.Fee.ToString().PadLeft(6,'0');
					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.SetMsgContent(bsmsg,2);
					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;
				}
					
			}
//			uint seq=this.getNextSequence();
//			MSG.CMPP_Submit submit=new CMPP3.Client.MSG.CMPP_Submit(seq);
//			string [] _desttermids=DestTermID.Split('-');
//			foreach(string desttermid in _desttermids)
//			{
//				submit.AddDestID(desttermid);
//			}
//			submit.AtTime="";//this.GetAtTime(DateTime.Now);
//			submit.DestTermType=0;
//			submit.FeeCode=Fee;
//			submit.FeeTerminalID="";
//			submit.FeeTerminalType=0;
//			submit.FeeType=FeeType;
//			submit.FeeUserType=FeeUserType;
//			submit.ifNeedReport=IfNeedReoport;
//			submit.LinkID=LinkID;
//			submit.MsgFormat=MsgFmt;
//			submit.MsgLevel=3;
//			submit.MsgSrc=this.SPID;
//			submit.Service_ID=ServiceCode;
//			submit.Src_Id=this.SpecialCode+LongCode;
//			submit.TpPid=Tp_Pid;
//			submit.TpUdhi=Tp_Udhi;
//			submit.ValId_Time="";//this.GetValidTime(DateTime.Now);
//			submit.SetMsgContent(MsgContent,MsgFmt);
//			QueueItem q=new QueueItem();
//			q.InQueueTime=DateTime.Now;
//			q.Msg=submit;
//			q.MsgSequence=seq;
//			q.MsgType=(uint)MSG.CMPP_COMMAND_ID.CMPP_SUBMIT;
//			this.AddItemToOutQueueToGateWay(q);
//			return seq;
		}
		/***********************私有函数*********************************************/
		/// <summary>
		/// 设置是否可以从待发送队列中提取数据进行发送
		/// </summary>
		/// <param name="ifCanRecv"></param>
		private void SetIfCanRecvItemFromOutQueue(bool ifCanRecv)
		{
			this.RWL_IfCanRecvItemFromOutQueue.AcquireWriterLock(-1);
			this.IfCanRecvItemFromOutQueue=ifCanRecv;
			this.RWL_IfCanRecvItemFromOutQueue.ReleaseWriterLock();
			Thread.Sleep(1);
		}
		private bool GetIfCanRecvItemFromOutQueue()
		{
			this.RWL_IfCanRecvItemFromOutQueue.AcquireReaderLock(-1);
			bool b=IfCanRecvItemFromOutQueue;
			this.RWL_IfCanRecvItemFromOutQueue.ReleaseReaderLock();
			Thread.Sleep(1);
			return b;
		}
		/// <summary>
		/// 获取是否可以向待发送队列写入数据
		/// </summary>
		/// <returns></returns>
		private bool GetIfCanAddItemToOutQueue()
		{
			this.RWL_IfCanAddItemToOutQueue.AcquireReaderLock(-1);
			bool b=this.IfCanAddItemToOutQueue;
			this.RWL_IfCanAddItemToOutQueue.ReleaseReaderLock();
			Thread.Sleep(1);
			return b;
		}
		/// <summary>
		/// 设置是否可以向待发送队列写入数据
		/// </summary>
		/// <param name="IfCanAdd"></param>
		private void SetIfCanAddItemToOutQueue(bool IfCanAdd)
		{
			this.RWL_IfCanAddItemToOutQueue.AcquireWriterLock(-1);
			this.IfCanAddItemToOutQueue=IfCanAdd;
			this.RWL_IfCanAddItemToOutQueue.ReleaseWriterLock();
			Thread.Sleep(1);
		}
		private int GetWaitQueueItemCount()
		{
			this.RWL_WaitQueue.AcquireReaderLock(-1);
			int i=this.WaitQueue.Count;
			this.RWL_WaitQueue.ReleaseReaderLock();
			Thread.Sleep(1);
			return i;
		}
		public void Stop()
		{
			this._Stop(1);
		}
		public int Start()
		{
			this.State=CMPPState.Starting;
			if(!this.ConnectToServer())
			{
				this.State=CMPPState.StartFailed;
				return -1;
			}
			if(!this.SendConnectMsg())
			{
				this.State=CMPPState.StartFailed;
				this.SeverSocket.Close();
				return -2;
			}
			this.RegisnterLastSentISMGMsgTime();
			this.RegisterLastRecvISMGMsgTime();
			DateTime t1=DateTime.Now;
			while(!this.isLogin)
			{
				byte[] buf=new byte[400];
				int recvsize;
				try
				{
					recvsize=this.SeverSocket.Receive(buf,0,buf.Length,SocketFlags.None);
					if(recvsize>=33)
					{
						MSG.Header head=new CMPP3.Client.MSG.Header(buf,0);
						if(head.Command_ID==(uint)MSG.CMPP_COMMAND_ID.CMPP_CONNECT_RESP)
						{
							//是登陆回复
							MSG.CMPP_Connect_Resp connectResp=new CMPP3.Client.MSG.CMPP_Connect_Resp(buf,0);
							if(this.onReceiveConnectRespHandler!=null)
							{
								ConnectRespEventArgs e=new ConnectRespEventArgs(connectResp);
								this.onReceiveConnectRespHandler(this,e);
							}
							if(connectResp.LoginSuccess)
							{
								//登陆成功
								this.isLogin=true;
								this.State=CMPPState.Started;
								this.SetIfCanAddItemToOutQueue(true);
								this.SetIfCanProc(true);
								this.SetIfCanRecvItemFromOutQueue(true);
								this.SetOutQueueItemToTempQueue();//将待发送队列中的数据全部放入缓冲队列
								if(this.onLoginSuccessHandler!=null)
								{
									EventArgs e=new EventArgs();
									this.onLoginSuccessHandler(this,e);
								}
								if(recvsize>33)
								{
									int RemainSize=recvsize-33;
									byte[] _bs=new byte[RemainSize];
									Array.Copy(buf,33,_bs,0,RemainSize);
									this.RWL_LastBytes.AcquireWriterLock(-1);
									this.LastBytes=_bs;
									this.RWL_LastBytes.ReleaseLock();
									Thread.Sleep(1);
								}
							}
							else
							{
								LoginFailedException lfe=new LoginFailedException();
								
								throw(lfe);
							}
						}
						else
						{
							if(this.onErrorHandler!=null)
							{
								ErrorEventArgs e=new ErrorEventArgs();
								e.ErrorMessage="登陆失败";
								e.MyMessage="发送了登陆信息,但接收时接收到的不是ConnectResp信息";
								this.onErrorHandler(this,e);
							}
							this.State=CMPPState.StartFailed;
							return -4;
						}
					}
				}
				catch(SocketException se)//SOCKET失败
				{
					this.SeverSocket.Close();
					if(this.onSocketCloseHandler!=null)
					{
						SocketClosedEventArgs e=new SocketClosedEventArgs(this.OutQueue,this.WaitQueue);
						this.onSocketCloseHandler(this,e);
					}
					if(this.onErrorHandler!=null)
					{
						ErrorEventArgs e=new ErrorEventArgs();
						e.ErrorMessage=se.Message;
						e.MyMessage="发送了登陆信息,但接收时SOCKET失败,函数Start()";
						this.onErrorHandler(this,e);
					}
					this.State=CMPPState.StartFailed;
					return -3;
				}
				catch(LoginFailedException)//登陆失败
				{
					this.SeverSocket.Close();
					if(this.onErrorHandler!=null)
					{
						ErrorEventArgs e=new ErrorEventArgs();
						e.ErrorMessage="登陆失败";
						e.MyMessage="接收到网关回复的ConnectResp,登陆失败,具体原因请参照,ConnectResp事件数据内容,当前已关闭TCP连接";
						this.onErrorHandler(this,e);
					}
					this.State=CMPPState.StartFailed;
					return -3;
				}
				catch(Exception ex)
				{
					this.SeverSocket.Close();
					if(this.onErrorHandler!=null)
					{
						ErrorEventArgs e=new ErrorEventArgs();
						e.ErrorMessage=ex.Message;
						e.MyMessage="登陆失败,TCP连接已经关闭";
						this.onErrorHandler(this,e);
					}
					this.State=CMPPState.StartFailed;
					return -3;
				}
				TimeSpan ts=DateTime.Now-t1;
				if(ts.TotalSeconds>=100)
				{
					break;
				}
			}
			if(this.isLogin)
			{
				this.StartThread();
				return 0;
			}
			else
			{
				this.State=CMPPState.StartFailed;
				return -5;
			}
			
		}
		//**************************************************************************************
		//						私有函数
		/// <summary>
		/// 将所有待发送队列中的数据放入缓冲队列
		/// </summary>
		private void SetOutQueueItemToTempQueue()
		{
			int i=0;
			while(true)
			{
				try
				{
					System.Messaging.Message msg=this.MSMQ_CMPP3GateWayService_OutQueue.Receive(System.TimeSpan.FromMilliseconds(300));
					if(msg==null)
					{
						i++;
					}
					else
					{
						try
						{
							QueueItem q=(QueueItem)msg.Body;
							if(q.MsgType==(uint)MSG.CMPP_COMMAND_ID.CMPP_SUBMIT)
							{
								this.AddQueueItemToBufferQueue(q);
							}
						}
						catch(Exception ex)
						{
							if(this.onErrorHandler!=null)
							{
								Client.ErrorEventArgs ea=new ErrorEventArgs();
								ea.MyMessage="将待发送队列中数据倒入缓冲队列时失败,函数SetOutQueueItemToTempQueue()";
								ea.ErrorMessage=ex.Message;
								this.onErrorHandler(this,ea);
							}
						}
					}

⌨️ 快捷键说明

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