📄 cmpp.cs
字号:
{
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 + -