//转自:
月光下的卡瓦博格
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
Cmpp.Components
{ /**//// <summary> /// CMPP30 的摘要说明。 /// </summary> public class CMPP30 { 变量以及初始值#region 变量以及初始值 protected string m_strSPID;//SP企业代码; protected string m_strUsername; protected string m_strPassword;//SP密码; protected string m_strAddress;//短信网关地址 protected int m_iPort;//短信网关端口号; protected static UInt32 m_iSeqID = 0;//命令的序号 protected int m_iSlidingWindowSize = 16;//滑动窗口大小(W) protected int m_iActiveTestSpan = 30;//ACTIVETEST的时间间隔(C,以秒为单位),标准为180 protected DateTime m_dtLastTransferTime;//最近一次网络传输时间 protected int m_iTimeOut = 60;//响应超时时间(T,以秒为单位) protected int m_iSendCount = 3;//最大发送次数(N) protected DATA_PACKAGE[] SlidingWindow = null; protected TcpClient m_TcpClient = null; protected NetworkStream m_NetworkStream = null; protected Queue m_MessageQueue = null;//消息队列,用于保存所有待发送数据 protected int m_iTcpClientTimeout = 5;//TcpClient接收和发送超时(以秒为单位) protected int m_iSendSpan = 10;//发送间隔,以毫秒为单位 #endregion 构造函数#region 构造函数 public CMPP30(string SPID, string Username, string Password, string Address, int Port) { PClsIni ini = new PClsIni(System.Windows.Forms.Application.StartupPath + "\\Option.ini"); if (ini.ExistINIFile()) { m_iSeqID = UInt32.Parse(ini.IniReadValue("CMPP", "SeqID")); m_iSlidingWindowSize = int.Parse(ini.IniReadValue("CMPP", "SlidingWindowSize")); m_iActiveTestSpan = int.Parse(ini.IniReadValue("CMPP", "ActiveTestSpan")); m_iTimeOut = int.Parse(ini.IniReadValue("CMPP", "TimeOut")); m_iSendCount = int.Parse(ini.IniReadValue("CMPP", "SendCount")); m_iTcpClientTimeout = int.Parse(ini.IniReadValue("CMPP", "TcpClientTimeout")); m_iSendSpan = int.Parse(ini.IniReadValue("CMPP", "SendSpan")); } m_strSPID = SPID; m_strUsername = Username; m_strPassword = Password; m_strAddress = Address; m_iPort = Port; SlidingWindow = new DATA_PACKAGE[m_iSlidingWindowSize];//初始化滑动窗口 for (int i = 0; i < m_iSlidingWindowSize; i++) SlidingWindow[i] = new DATA_PACKAGE(); m_MessageQueue = new Queue(); } #endregion Constants#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 System.Threading.Thread m_SendThread = null; protected System.Threading.Thread m_ReceiveThread = null; protected AutoResetEvent m_eventSendExit = new AutoResetEvent(false); protected AutoResetEvent m_eventReceiveExit = new AutoResetEvent(false); protected AutoResetEvent m_eventConnect = new AutoResetEvent(false); protected AutoResetEvent m_eventDisconnect = new AutoResetEvent(false); protected ManualResetEvent m_eventSend = new ManualResetEvent(false); protected ManualResetEvent m_eventReceive = new 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 bOK = true; ActiveTest(); Monitor.Enter(SlidingWindow); for (int i = 0; i < m_iSlidingWindowSize; i++)//首先用消息队列中的数据填充滑动窗口 { if (SlidingWindow[i].Status == 0) { DATA_PACKAGE dp = new DATA_PACKAGE(); dp.Data = null; Monitor.Enter(m_MessageQueue); if (m_MessageQueue.Count > 0) { dp = (DATA_PACKAGE)m_MessageQueue.Dequeue(); SlidingWindow[i] = dp; } Monitor.Exit(m_MessageQueue); } } for (int i = 0; i < m_iSlidingWindowSize; i++) { DATA_PACKAGE dp = SlidingWindow[i]; if ((dp.Status == 1) && (dp.SendCount == 0))//第一次发送 { bOK = Send(dp); if ((bOK) && (dp.Command > 0x80000000))//发送的是Response类的消息,不需等待Response { SlidingWindow[i].Status = 0;//清空窗口 } else if ((bOK) && (dp.Command < 0x80000000))//发送的是需要等待Response的消息 { SlidingWindow[i].SendTime = DateTime.Now; SlidingWindow[i].SendCount++; } else { bOK = false; break;//网络出错 } } else if ((dp.Status == 1) && (dp.SendCount > 0))//第N次发送 { if (dp.SendCount > m_iSendCount - 1)//已发送m_iSendCount次,丢弃数据包 { SlidingWindow[i].Status = 0;//清空窗口 if (dp.Command == CMPP30.CMD_ACTIVE_TEST)//是ActiveTest { bOK = false; break;//ActiveTest出错 } } else { TimeSpan ts = DateTime.Now - dp.SendTime; if (ts.TotalSeconds >= m_iTimeOut)//超时后未收到回应包 { bOK = Send(dp);//再次发送 if (bOK) { SlidingWindow[i].SendTime = DateTime.Now; SlidingWindow[i].SendCount++; } else { bOK = false; break;//网络出错 } } } } } Monitor.Exit(SlidingWindow); if (!bOK) { Close();//关闭连接 Thread.Sleep(5000);//等待5秒 m_eventSend.Reset(); m_eventConnect.Set(); } } Thread.Sleep(1); } } 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 Head = ReadHead(); if (Head.CommandID == CMPP30.CMD_SUBMIT_RESP) { ReadSubmitResp(Head); } else if (Head.CommandID == CMPP30.CMD_ACTIVE_TEST) { ActiveTestResponse(Head.SequenceID); } else if (Head.CommandID == CMPP30.CMD_ACTIVE_TEST_RESP) { ReadActiveTestResponse(Head); } else if (Head.CommandID == CMPP30.CMD_DELIVER) { ReadDeliver(Head); } else if (Head.CommandID == CMPP30.CMD_ERROR)//网络故障 { m_eventReceive.Reset(); m_eventDisconnect.Set(); } } Thread.Sleep(1); } } #endregion SMSEvents#region SMSEvents public event SMSEventHandler SMSStateChanged; protected void RaiseEvent(SMS_STATE State, Object Data) { if (null != SMSStateChanged) { SMSEventArgs e = new SMSEventArgs(); e.Time = DateTime.Now; e.State = State; e.Data = Data; SMSStateChanged(this, e); } } #endregion 私有方法#region 私有方法 protected UInt32 TimeStamp(DateTime dt) { string str = String.Format("{0:MMddhhmmss}", dt); return Convert.ToUInt32(str); } protected UInt32 CreateID() { UInt32 id = m_iSeqID; m_iSeqID++; if (m_iSeqID > UInt32.MaxValue) m_iSeqID = 0; return id; } protected Byte[] CreateDigest(DateTime dt) { int iLength = 25 + m_strPassword.Length; Byte[] btContent = new Byte[iLength]; Array.Clear(btContent, 0, iLength); int iPos = 0; foreach (char ch in m_strSPID) { btContent[iPos] = (Byte)ch; iPos++; } iPos += 9; foreach (char ch in m_strPassword) { btContent[iPos] = (Byte)ch; iPos++; } string strTimeStamp = String.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_TcpClient = null; m_NetworkStream = null; return true; } protected bool Connect() { bool bOK = true; string strError = string.Empty; CMPP_CONNECT_RESP resp = new CMPP_CONNECT_RESP(); try { m_TcpClient = new TcpClient(); m_TcpClient.ReceiveTimeout = m_TcpClient.SendTimeout = m_iTcpClientTimeout * 1000; m_TcpClient.Connect(m_strAddress, m_iPort); m_NetworkStream = m_TcpClient.GetStream(); DateTime dt = DateTime.Now; CMPP_CONNECT conn = new CMPP_CONNECT(); conn.Head = new CMPP_HEAD(); conn.Head.CommandID = CMPP30.CMD_CONNECT; conn.Head.SequenceID = CreateID(); conn.SourceAddress = m_strSPID; conn.TimeStamp = TimeStamp(dt); conn.AuthenticatorSource = CreateDigest(dt); conn.Version = CMPP_VERSION_30; Byte[] buffer = conn.GetBuffer(); m_NetworkStream.Write(buffer, 0, (Int32)conn.Head.TotalLength); int iSpan = 0; bool bTimeOut = false; while (!m_NetworkStream.DataAvailable)//等待RESPONSE 5秒 { Thread.Sleep(10); iSpan++; if (iSpan > 500) { bTimeOut = true; break; } } if (!bTimeOut) { CMPP_HEAD Head = ReadHead(); if (Head.CommandID == CMD_CONNECT_RESP) { resp = ReadConnectResp(Head); if (resp.Status == 0) bOK = true; else { bOK = false; strError = "未正确接收CONNECT_RESP"; } } } else { bOK = false; strError = "等待CONNECT_RESP超时"; } } catch (Exception e) { strError = e.Message; bOK = false; } if (bOK) RaiseEvent(SMS_STATE.SP_CONNECT, resp); else RaiseEvent(SMS_STATE.SP_CONNECT_ERROR, strError); return bOK; } protected bool Disconnect() { bool bOK = true; string strError = string.Empty; try { DateTime dt = DateTime.Now; CMPP_HEAD Head = new CMPP_HEAD(); Head.CommandID = CMPP30.CMD_TERMINATE; Head.SequenceID = CreateID(); Head.TotalLength = (UInt32)Marshal.SizeOf(Head); Byte[] buffer = Head.GetBuffer(); m_NetworkStream.Write(buffer, 0, (Int32)Head.TotalLength); int iSpan = 0; bool bTimeOut = false; while (!m_NetworkStream.DataAvailable)//等待RESPONSE 5秒 { Thread.Sleep(10); iSpan++; if (iSpan > 500) { bTimeOut = true; break; } } if (!bTimeOut) { Head = ReadHead(); if (Head.CommandID == CMD_TERMINATE_RESP) bOK = true; else { bOK = false; strError = "未正确接收TERMINATE_RESP"; } } else { bOK = false; strError = "等待TERMINATE_RESP超时"; } } catch (Exception ex) { bOK = false; strError = ex.Message; } if (m_NetworkStream != null) m_NetworkStream.Close(); if (m_TcpClient != null) m_TcpClient.Close(); m_TcpClient = null; m_NetworkStream = null; 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 bOK = true; string strError = string.Empty; SMS_STATE state = SMS_STATE.UNKNOW_ERROR; try { Thread.Sleep(m_iSendSpan); Byte[] btData = null; if (dp.Command == CMD_ACTIVE_TEST) { btData = ((CMPP_HEAD)dp.Data).GetBuffer(); state = SMS_STATE.ACTIVE_TEST; } else if (dp.Command == CMD_ACTIVE_TEST_RESP) { btData = ((CMPP_ACTIVE_TEST_RESP)dp.Data).GetBuffer(); state = SMS_STATE.ACTIVE_TEST_RESPONSE; } else if (dp.Command == CMD_DELIVER_RESP) { btData = ((CMPP_DELIVER_RESP)dp.Data).GetBuffer(); state = SMS_STATE.DELIVER_RESPONSE; } else if (dp.Command == CMD_SUBMIT) { btData = ((CMPP_SUBMIT)dp.Data).GetBuffer(); state = SMS_STATE.SUBMIT; } m_NetworkStream.Write(btData, 0, btData.Length); m_dtLastTransferTime = DateTime.Now; } catch (Exception ex) { bOK = false; strError = ex.Message; } if (bOK) { RaiseEvent(state, dp.Data); } else { if (state == SMS_STATE.ACTIVE_TEST) state = SMS_STATE.ACTIVE_TEST_ERROR; else if (state == SMS_STATE.ACTIVE_TEST_RESPONSE) state = SMS_STATE.ACTIVE_TEST_RESPONSE_ERROR; else if (state == SMS_STATE.DELIVER_RESPONSE) state = SMS_STATE.DELIVER_RESPONSE_ERROR; else if (state == SMS_STATE.SUBMIT) state = SMS_STATE.SUBMIT_ERROR; RaiseEvent(state, strError); } return bOK; } protected CMPP_HEAD ReadHead() { CMPP_HEAD head = new CMPP_HEAD(); head.CommandID = 0; Byte[] buffer = new Byte[12]; try { if (m_NetworkStream.DataAvailable) { m_NetworkStream.Read(buffer, 0, buffer.Length); head.TotalLength = (UInt32)Utility.NetBytesToInt(buffer, 0, 4); head.CommandID = (UInt32)Utility.NetBytesToInt(buffer, 4, 4); head.SequenceID = (UInt32)Utility.NetBytesToInt(buffer, 8, 4); } } catch { head.CommandID = CMD_ERROR; } return head; } protected CMPP_CONNECT_RESP ReadConnectResp(CMPP_HEAD Head) { CMPP_CONNECT_RESP resp = new CMPP_CONNECT_RESP(); resp.Head = Head; try { if (m_NetworkStream.DataAvailable) { Byte[] buffer = new Byte[resp.Head.TotalLength - Marshal.SizeOf(resp.Head)]; m_NetworkStream.Read(buffer, 0, buffer.Length); resp.Status = (UInt32)Utility.NetBytesToInt(buffer, 0, 4); resp.AuthenticatorISMG = new Byte[16]; Array.Copy(buffer, 4, resp.AuthenticatorISMG, 0, 16); resp.Version = buffer[buffer.Length - 1]; } } catch { resp.Head.CommandID = CMD_ERROR; } return resp; } protected CMPP_SUBMIT_RESP ReadSubmitResp(CMPP_HEAD Head) { CMPP_SUBMIT_RESP resp = new CMPP_SUBMIT_RESP(); resp.Head = Head; string strError = string.Empty; bool bOK = true; try { if (m_NetworkStream.DataAvailable) { Byte[] buffer = new Byte[resp.Head.TotalLength - Marshal.SizeOf(resp.Head)]; m_NetworkStream.Read(buffer, 0, buffer.Length); //resp.MsgID=(UInt64)Utility.NetBytesToInt(buffer,0,8); resp.Msg_ID = (UInt64)BitConverter.ToUInt64(buffer, 0); resp.Result = (UInt32)Utility.NetBytesToInt(buffer, 8, 4); Monitor.Enter(SlidingWindow); for (int i = 0; i < m_iSlidingWindowSize; i++) { if ((SlidingWindow[i].Status == 1) &&//已发送,等待回应 (SlidingWindow[i].SequenceID == resp.Head.SequenceID) &&//序列号相同 (SlidingWindow[i].Command == CMD_SUBMIT))//是Submit { SlidingWindow[i].Status = 0;//清空窗口 break; } } Monitor.Exit(SlidingWindow); } } catch (Exception ex) { resp.Head.CommandID = CMD_ERROR; strError = ex.Message; bOK = false; } if (bOK) RaiseEvent(SMS_STATE.SUBMIT_RESPONSE, resp); else RaiseEvent(SMS_STATE.SUBMIT_RESPONSE_ERROR, strError); return resp; } protected CMPP_DELIVER ReadDeliver(CMPP_HEAD Head) { CMPP_DELIVER deliver = new CMPP_DELIVER(); deliver.Head = Head; string strError = string.Empty; try { if (m_NetworkStream.DataAvailable) { Byte[] buffer = new Byte[deliver.Head.TotalLength - Marshal.SizeOf(deliver.Head)]; m_NetworkStream.Read(buffer, 0, buffer.Length); deliver.Init(buffer); DeliverResponse(deliver.Head.SequenceID, deliver.Msg_ID, 0); } } catch (Exception ex) { deliver.Head.CommandID = CMD_ERROR; strError = ex.Message; } if ((deliver.Head.CommandID == CMD_DELIVER) && (deliver.Registered_Delivery == 0))/**/////是短消息 { RaiseEvent(SMS_STATE.DELIVER, deliver); } else if ((deliver.Head.CommandID == CMD_DELIVER) && (deliver.Registered_Delivery == 1))/**/////是状态报告 { RaiseEvent(SMS_STATE.REPORT, deliver); } else//错误 { RaiseEvent(SMS_STATE.DELIVER_ERROR, strError); } return deliver; } protected bool DeliverResponse(UInt32 SequenceID, UInt64 Msg_Id, UInt32 Result) { bool bOK = true; string strError = string.Empty; CMPP_DELIVER_RESP resp = new CMPP_DELIVER_RESP(); resp.Head = new CMPP_HEAD(); resp.Head.CommandID = CMPP30.CMD_DELIVER_RESP; resp.Head.SequenceID = SequenceID; resp.Msg_Id = Msg_Id; resp.Result = Result; DATA_PACKAGE dp = new DATA_PACKAGE(); dp.SequenceID = resp.Head.SequenceID; dp.Command = resp.Head.CommandID; dp.SendCount = 0; dp.Data = resp; dp.Status = 1; Monitor.Enter(m_MessageQueue); m_MessageQueue.Enqueue(dp); Monitor.Exit(m_MessageQueue); return bOK; } protected bool ActiveTest() { bool bOK = true; TimeSpan ts = DateTime.Now - m_dtLastTransferTime; if (ts.TotalSeconds > m_iActiveTestSpan) { CMPP_HEAD Head = new CMPP_HEAD(); Head.CommandID = CMPP30.CMD_ACTIVE_TEST; Head.SequenceID = CreateID(); Head.TotalLength = 12; DATA_PACKAGE dp = new DATA_PACKAGE(); dp.SequenceID = Head.SequenceID; dp.Command = Head.CommandID; dp.SendCount = 0; dp.Data = Head; dp.Status = 1; Monitor.Enter(m_MessageQueue); m_MessageQueue.Enqueue(dp); Monitor.Exit(m_MessageQueue); } return bOK; } protected CMPP_ACTIVE_TEST_RESP ReadActiveTestResponse(CMPP_HEAD Head) { CMPP_ACTIVE_TEST_RESP resp = new CMPP_ACTIVE_TEST_RESP(); resp.Head = Head; string strError = string.Empty; bool bOK = true; try { if (m_NetworkStream.DataAvailable) { Byte[] buffer = new Byte[resp.Head.TotalLength - Marshal.SizeOf(resp.Head)]; m_NetworkStream.Read(buffer, 0, buffer.Length); resp.Reserved = buffer[0]; Monitor.Enter(SlidingWindow); for (int i = 0; i < m_iSlidingWindowSize; i++) { if ((SlidingWindow[i].Status == 1) &&//已发送,等待回应 (SlidingWindow[i].SequenceID == resp.Head.SequenceID) &&//序列号相同 (SlidingWindow[i].Command == CMD_ACTIVE_TEST))//是ACTIVE_TEST { SlidingWindow[i].Status = 0;//清空窗口 break; } } Monitor.Exit(SlidingWindow); } } catch (Exception ex) { resp.Head.CommandID = CMD_ERROR; strError = ex.Message; bOK = false; } if (bOK) RaiseEvent(SMS_STATE.ACTIVE_TEST_RESPONSE, resp); else RaiseEvent(SMS_STATE.ACTIVE_TEST_RESPONSE_ERROR, strError); return resp; } protected bool ActiveTestResponse(UInt32 SequenceID) { bool bOK = true; CMPP_ACTIVE_TEST_RESP resp = new CMPP_ACTIVE_TEST_RESP(); resp.Head = new CMPP_HEAD(); resp.Head.CommandID = CMPP30.CMD_ACTIVE_TEST_RESP; resp.Head.SequenceID = SequenceID; resp.Reserved = 0; DATA_PACKAGE dp = new DATA_PACKAGE(); dp.SequenceID = resp.Head.SequenceID; dp.Command = resp.Head.CommandID; dp.SendCount = 0; dp.Data = resp; dp.Status = 1; Monitor.Enter(m_MessageQueue); m_MessageQueue.Enqueue(dp); Monitor.Exit(m_MessageQueue); return bOK; } #endregion 公有方法#region 公有方法 /**//// <summary> /// 开始启动发送和接收线程 /// </summary> public void StartThread() { if (m_SendThread == null) { m_dtLastTransferTime = DateTime.Now; m_SendThread = new Thread(new ThreadStart(this.SendThreadProc)); m_SendThread.IsBackground = true; m_SendThread.Name = m_strSPID + "_Send"; m_SendThread.Start(); } if (m_ReceiveThread == null) { m_ReceiveThread = new Thread(new ThreadStart(this.ReceiveThreadProc)); m_ReceiveThread.IsBackground = true; m_ReceiveThread.Name = m_strSPID + "_Receive"; m_ReceiveThread.Start(); } m_eventConnect.Set(); } /**//// <summary> /// 结束发送和接收线程 /// </summary> public void EndThread() { m_eventSend.Reset(); m_eventReceive.Reset(); m_eventReceiveExit.Set(); m_eventSendExit.Set(); } /**//// <summary> /// SubMit发送函数 /// </summary> /// <param name="Message">信息内容</param> /// <param name="Destination">接收短信的MSISDN号码</param> /// <param name="Source">SP的服务代码</param> /// <param name="ServiceID">业务标识,是数字、字母和符号的组合</param> /// <param name="Coding">信息格式: 0:ASCII串;3:短信写卡操作4:二进制信息;8:UCS2编码;15:含GB汉字 </param> /// <param name="NeedReport">是否要求返回状态确认报告: 0:不需要; 1:需要。</param> /// <param name="FeeUserType">计费用户类型字段:0:对目的终端MSISDN计费;1:对源终端MSISDN计费;2:对SP计费;3:表示本字段无效,对谁计费参见Fee_terminal_Id字段。</param> /// <param name="FeeType">资费类别:01:对“计费用户号码”免费;02:对“计费用户号码”按条计信息费;03:对“计费用户号码”按包月收取信息费。</param> /// <param name="InfoFee">资费代码(以分为单位)</param> /// <param name="FeeUser">被计费用户的号码,当Fee_UserType为3时该值有效,当Fee_UserType为0、1、2时该值无意义</param> /// <param name="LinkID">点播业务使用的LinkID,非点播类业务的MT流程不使用该字段</param> /// <returns>是否发送成功</returns> public bool Submit(string Message, string[] Destination, string Source, string ServiceID, CODING Coding, bool NeedReport, byte FeeUserType, byte FeeType, int InfoFee, string FeeUser, string LinkID) { bool bOK = true; string strError = string.Empty; CMPP_SUBMIT submit = new CMPP_SUBMIT(); submit.Head = new CMPP_HEAD(); submit.Head.CommandID = CMPP30.CMD_SUBMIT; submit.Head.SequenceID = CreateID(); submit.Msg_ID = 0; submit.Pk_Total = 1; submit.Pk_Number = 1; submit.Registered_Delivery = Convert.ToByte(NeedReport); submit.Msg_Level = 0; submit.Service_Id = ServiceID; submit.Fee_UserType = FeeUserType; submit.Fee_Terminal_Id = FeeUser; submit.Fee_Terminal_Type = 0;//真实号码 submit.TP_Pid = 0; submit.TP_Udhi = 0; submit.Msg_Fmt = (Byte)Coding; submit.Msg_Src = m_strSPID; submit.FeeType = string.Format("{0:d2}", FeeType); submit.FeeCode = InfoFee.ToString(); submit.Valid_Time = string.Empty; submit.At_Time = string.Empty; submit.Src_Id = Source; submit.DestUsr_Tl = (Byte)Destination.Length; submit.Dest_Terminal_ID = Destination; submit.Dest_Terminal_Type = 0;//真实号码 submit.Msg_Length = (Byte)Utility.CountLength(Message, Coding); submit.Msg_Content = Message; submit.LinkID = LinkID; DATA_PACKAGE dp = new DATA_PACKAGE(); dp.SequenceID = submit.Head.SequenceID; dp.Command = submit.Head.CommandID; dp.SendCount = 0; dp.Data = submit; dp.Status = 1; Monitor.Enter(m_MessageQueue); m_MessageQueue.Enqueue(dp); Monitor.Exit(m_MessageQueue); return bOK; } #endregion } /**//// <summary> /// 异步发送回调函数 /// </summary> public delegate bool CMPPAsyncSubmit(string Message, string[] Destination, string Source, string ServiceID, CODING Coding, bool NeedReport, byte FeeUserType, byte FeeType, int InfoFee, string FeeUser, string LinkID);}
转载于:https://www.cnblogs.com/EndPoint/archive/2007/01/31/635506.html
相关资源:CMPP30标准NET异步收发
转载请注明原文地址: https://win8.8miu.com/read-1485099.html