C# 网通短信网关 SGIP

对网通必须使用两个SOCKET进行连接 你给网通提供的端口 是需要要监听的.发送你随意找个端口就可以了.

 

使用方法

 

 

m_Connection = new SGIP.SGIPConnection(GetWayConfig.AddressSP, GetWayConfig.PortSP, GetWayConfig.AddressLocal, GetWayConfig.PortLocal);
            m_Connection.CommandResp += new SMSSGIP.SGIP.SGIPConnection.DelegateCommandResp(m_Connection_CommandResp);
            m_Connection.CommandListen += new SMSSGIP.SGIP.SGIPConnection.DelegateCommandListen(m_Connection_CommandListen);

 

发送

 

  m_Connection.SetCommandSrcNodeSequence(_CommandList);
            if (m_Connection.SendCommandList(_CommandList) == false)

 

 

_CommandList为命令列表..先是BindCommand然后是SubmitCommand ..

 

 

对于BusinessKey不是SGIP里的内容 是为了方便业务方面的操作.

 

 

下面是全部的类

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.IO;

namespace SMSSGIP.SGIP
{
    public class SGIPConnection
    {
        private IPEndPoint m_AddressSP = null;
        private IPEndPoint m_AddressLocalOfWrite = null;
        private IPEndPoint m_AddressLocalOfRead = null;
        private uint m_SrcNodeSequence = 1;
        private Socket m_ThreadSocket = null;

        public delegate void DelegateCommandResp(SGIPCommand p_Command);
        public delegate void DelegateCommandListen(SGIPCommand p_Command,ref SGIPCommand p_Resp);
        public event DelegateCommandResp CommandResp;
        public event DelegateCommandListen CommandListen;

        /// <summary>
        /// 发送使用类
        /// </summary>
        public class SGIPSocketDispatch
        {
            private Socket m_DataSocket = null;
            private Dictionary<uint, SGIPCommand> m_CommandList = new Dictionary<uint, SGIPCommand>();
            private MemoryStream m_CommandStream = new MemoryStream();

            public MemoryStream CommandStream
            {
                get { return m_CommandStream; }
                set { m_CommandStream = value; }
            }
            public Socket DataSocket
            {
                get { return m_DataSocket; }
                set { m_DataSocket = value; }
            }
            public Dictionary<uint, SGIPCommand> CommandList
            {
                get { return m_CommandList; }
                set { m_CommandList = value; }
            }
        }

        /// <summary>
        /// SGIP连接
        /// </summary>
        /// <param name="p_SPAddress">SP地址</param>
        /// <param name="p_SPPort">SP端口</param>
        /// <param name="p_LocalAddress">本地地址</param>
        /// <param name="p_LocalWritePort">本地发送端口</param>
        /// <param name="p_LoaclReadPort">本地监听端口</param>
        public SGIPConnection(string p_AddressSP, int p_PortSP, string p_LocalAddress, int p_PortLoaclRead)
        {
            m_AddressSP = new IPEndPoint(IPAddress.Parse(p_AddressSP), p_PortSP);
            m_AddressLocalOfWrite = new IPEndPoint(IPAddress.Parse(p_LocalAddress), 0);
            m_AddressLocalOfRead = new IPEndPoint(IPAddress.Parse(p_LocalAddress), p_PortLoaclRead);
        }

        public void SetCommandSrcNodeSequence(List<SGIPCommand> p_CommandList)
        {
            for (int i = 0; i != p_CommandList.Count; i++)
            {
                m_SrcNodeSequence++;
                p_CommandList[i].SGIP_SrcNodeSequence = m_SrcNodeSequence;
            }
        }

        /// <summary>
        /// 发送状态集合
        /// </summary>
        /// <param name="p_CommandList">命令列表</param>
        public bool SendCommandList(List<SGIPCommand> p_CommandList)
        {
            try
            {
                SGIPSocketDispatch _Socket = new SGIPSocketDispatch();
                _Socket.DataSocket = new Socket(m_AddressLocalOfWrite.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
                m_AddressLocalOfWrite.Port = 0;
                _Socket.DataSocket.Bind(m_AddressLocalOfWrite);
                _Socket.DataSocket.Connect(m_AddressSP);
                _Socket.DataSocket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, new AsyncCallback(Read), _Socket);  //建立异步读取 

                for (int i = 0; i != p_CommandList.Count; i++)
                {
                    byte[] _SendBytes = p_CommandList[i].GetMessageBytes();
                    _Socket.CommandList.Add(p_CommandList[i].SGIP_SrcNodeSequence, p_CommandList[i]);
                    _Socket.DataSocket.BeginSend(_SendBytes, 0, _SendBytes.Length, SocketFlags.None, null, _Socket);
                }
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 获取返回的数据包
        /// </summary>
        /// <param name="p_Data"></param>
        private void Read(IAsyncResult p_Data)
        {
            SGIPSocketDispatch _Socket = (SGIPSocketDispatch)p_Data.AsyncState; //获取Socket对象
            int _ReadCount = _Socket.DataSocket.Available;  //获得包大小
            if (_ReadCount != 0)
            {
                try
                {
                    byte[] _Byte = new byte[_ReadCount];   //建立要接收的对象信息
                    _Socket.DataSocket.Receive(_Byte, 0, _ReadCount, SocketFlags.None);
                    _Socket.CommandStream.Write(_Byte, 0, _ReadCount);
                }
                catch
                {
                    _Socket.DataSocket.Close();
                    return;
                }
                List<SGIPCommand> _RespCommand = GetCommand(_Socket);

                for (int i = 0; i != _RespCommand.Count; i++)
                {
                    if (_Socket.CommandList.ContainsKey(_RespCommand[i].SGIP_SrcNodeSequence))
                    {
                        _Socket.CommandList[_RespCommand[i].SGIP_SrcNodeSequence].RespCommand.Add(_RespCommand[i]);
                        if (CommandResp != null) CommandResp(_Socket.CommandList[_RespCommand[i].SGIP_SrcNodeSequence]);
                    }
                }
            }
            try
            {
                _Socket.DataSocket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, new AsyncCallback(Read), _Socket); //开始读取
            }
            catch
            {
                _Socket.DataSocket.Close();
            }
        }

        /// <summary>
        /// 根据获取的数据获取返回的COMMAND信息
        /// </summary>
        /// <param name="p_Socket"></param>
        /// <param name="p_Command"></param>
        private List<SGIPCommand> GetCommand(SGIPSocketDispatch p_Socket)
        {
            List<SGIPCommand> _CommandList = new List<SGIPCommand>();
            if (p_Socket.CommandStream.Length > 4)
            {
                int _Index = 0;
                byte[] _SocketBytes = p_Socket.CommandStream.ToArray();
                while (true)
                {
                    if (_Index >= _SocketBytes.Length)
                    {
                        p_Socket.CommandStream = new MemoryStream();
                        p_Socket.CommandStream.Write(_SocketBytes, _Index, _SocketBytes.Length - _Index);
                        break;
                    }
                    byte[] _PackesLength = new byte[4];
                    Array.Copy(_SocketBytes, _Index, _PackesLength, 0, 4);
                    Array.Reverse(_PackesLength);
                    int _PackCount = BitConverter.ToInt32(_PackesLength, 0);

                    if (_SocketBytes.Length >= _PackCount)
                    {
                        byte[] _CommandBytes = new byte[_PackCount];
                        Array.Copy(_SocketBytes, _Index, _CommandBytes, 0, _PackCount);
                        SGIPCommand _RespCommand = SGIPCommand.CreateCommand(new MemoryStream(_CommandBytes));
                        _CommandList.Add(_RespCommand);

                        _Index += _PackCount;
                    }
                }
            }
            return _CommandList;

        }

        /// <summary>
        /// 开始监听
        /// </summary>
        /// <returns></returns>
        public bool StartThread()
        {
            try
            {
                if (m_ThreadSocket != null) return false;
                m_ThreadSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                m_ThreadSocket.Bind(m_AddressLocalOfRead);
                m_ThreadSocket.Listen(10);
                m_ThreadSocket.BeginAccept(new AsyncCallback(OnConnectRequest), m_ThreadSocket);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 监听连接
        /// </summary>
        /// <param name="p_Data"></param>
        private void OnConnectRequest(IAsyncResult p_Data)
        {
            try
            {
                Socket _SocketListen = (Socket)p_Data.AsyncState;
                SGIPSocketDispatch _Socket = new SGIPSocketDispatch();
                _Socket.DataSocket = _SocketListen.EndAccept(p_Data);
                _SocketListen.BeginAccept(new AsyncCallback(OnConnectRequest), _SocketListen);
                _Socket.DataSocket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, new AsyncCallback(OnRecievedData), _Socket);
            }
            catch
            {
            }
        }

        /// <summary>
        /// 开始获取数据
        /// </summary>
        /// <param name="p_Data"></param>
        private void OnRecievedData(IAsyncResult p_Data)
        {
            try
            {
                SGIPSocketDispatch _Socket = (SGIPSocketDispatch)p_Data.AsyncState;
                int _ReadCount = _Socket.DataSocket.Available;  //获得包大小
                if (_ReadCount != 0)
                {
                    byte[] _Byte = new byte[_ReadCount];   //建立要接收的对象信息
                    _Socket.DataSocket.Receive(_Byte, 0, _ReadCount, SocketFlags.None);
                    _Socket.CommandStream.Write(_Byte, 0, _ReadCount);
                    List<SGIPCommand> _RespCommand = GetCommand(_Socket);

                    for (int i = 0; i != _RespCommand.Count; i++)
                    {
                        SGIPCommand _Command = null;
                        if (CommandListen != null) CommandListen(_RespCommand[i],ref _Command);
                        if (_Command != null)
                        {
                            byte[] _ValueBytes = _Command.GetMessageBytes();
                            _Socket.DataSocket.BeginSend(_ValueBytes, 0, _ValueBytes.Length, SocketFlags.None, null, _Socket);                       
                        }
                    }
                }   
                _Socket.DataSocket.BeginReceive(new byte[0], 0, 0, SocketFlags.None, new AsyncCallback(OnRecievedData), _Socket);
            }
            catch
            {
            }
        }
    }

    public class SGIPCommand
    {
        private MemoryStream m_MemoryStraem = new MemoryStream();
        private string m_BusinessKey = "";

        public string BusinessKey
        {
            get { return m_BusinessKey; }
            set { m_BusinessKey = value; }
        }
   
        private List<SGIPCommand> m_RespCommand = new List<SGIPCommand>();

        public List<SGIPCommand> RespCommand
        {
            get { return m_RespCommand; }
            set { m_RespCommand = value; }
        }


        public SGIPCommand()
        {
            m_MemoryStraem.Write(new byte[20], 0, 20);
        }

        /// <summary>
        /// 消息的总长度
        /// </summary>
        public uint SGIP_PackageLength { get { return (uint)m_MemoryStraem.Length; } }
        /// <summary>
        /// 命令ID
        /// </summary>
        protected Commands Command
        {
            get { return (Commands)ReadUint(4); }
            set { WriteUint((uint)value, 4); }
        }
        /// <summary>
        /// 序列号
        /// </summary>
        public uint SGIP_SrcNodeSequence
        {
            get { return ReadUint(8); }
            set { WriteUint((uint)value, 8); }
        }
        /// <summary>
        /// 日期
        /// </summary>
        public uint SGIP_DateSequence
        {
            get { return ReadUint(12); }
            set { WriteUint((uint)value, 12); }
        }
        /// <summary>
        /// 保留
        /// </summary>
        public uint SGIP_MsgSequence
        {
            get { return ReadUint(16); }
            set { WriteUint((uint)value, 16); }
        }
        /// <summary>
        /// 获取命令行的字节
        /// </summary>
        /// <returns></returns>
        public byte[] GetMessageBytes()
        {
            return m_MemoryStraem.ToArray();
        }

 

        #region 字节写入和读
        /// <summary>
        /// 在命令里获取一个Uint
        /// </summary>
        /// <param name="p_StarIndex"></param>
        /// <returns></returns>
        protected uint ReadUint(int p_StarIndex)
        {
            byte[] _ValueBytes = new byte[4];
            m_MemoryStraem.Position = p_StarIndex;
            m_MemoryStraem.Read(_ValueBytes, 0, 4);
            Array.Reverse(_ValueBytes);
            m_MemoryStraem.Position = m_MemoryStraem.Length;
            return BitConverter.ToUInt32(_ValueBytes, 0);
        }
        /// <summary>
        /// 获取一个字节
        /// </summary>
        /// <param name="p_StarIndex"></param>
        /// <returns></returns>
        protected byte ReadByte(int p_StarIndex)
        {
            m_MemoryStraem.Position = p_StarIndex;
            byte _Value = (byte)m_MemoryStraem.ReadByte();
            m_MemoryStraem.Position = m_MemoryStraem.Length;
            return _Value;
        }
        /// <summary>
        /// 获取字符串
        /// </summary>
        /// <param name="p_StarIndex"></param>
        /// <param name="p_Value"></param>
        /// <returns></returns>
        protected String ReadString(int p_StarIndex, int p_MaxCount)
        {
            byte[] _Value = new byte[p_MaxCount];
            m_MemoryStraem.Position = p_StarIndex;
            m_MemoryStraem.Read(_Value, 0, p_MaxCount);
            m_MemoryStraem.Position = m_MemoryStraem.Length;
            return Encoding.ASCII.GetString(_Value);
        }
        /// <summary>
        /// 读取字节流
        /// </summary>
        /// <param name="p_StarIndex"></param>
        /// <param name="p_MaxCount"></param>
        /// <returns></returns>
        protected byte[] ReadBytes(int p_StarIndex, int p_MaxCount)
        {
            byte[] _Value = new byte[p_MaxCount];
            m_MemoryStraem.Position = p_StarIndex;
            m_MemoryStraem.Read(_Value, 0, p_MaxCount);
            return _Value;
        }

        /// <summary>
        /// 写入一个
        /// </summary>
        /// <param name="p_Value"></param>
        protected void WriteUint(uint p_Value, int p_StarIndex)
        {
            m_MemoryStraem.Position = p_StarIndex;
            byte[] _ValueBytes = BitConverter.GetBytes(p_Value);
            Array.Reverse(_ValueBytes);
            m_MemoryStraem.Write(_ValueBytes, 0, 4);
        }
        /// <summary>
        /// 写入String
        /// </summary>
        /// <param name="p_Value"></param>
        /// <param name="p_MaxBytes"></param>
        protected void WriteString(string p_Value, int p_StarIndex, int p_MaxBytes)
        {
            m_MemoryStraem.Position = p_StarIndex;
            byte[] _WriteBytes = System.Text.Encoding.ASCII.GetBytes(p_Value);
            m_MemoryStraem.Write(_WriteBytes, 0, _WriteBytes.Length > p_MaxBytes ? p_MaxBytes : _WriteBytes.Length);
            if (p_MaxBytes > _WriteBytes.Length) m_MemoryStraem.Write(new byte[p_MaxBytes - _WriteBytes.Length], 0, p_MaxBytes - _WriteBytes.Length);
        }
        /// <summary>
        /// 写入一个字节
        /// </summary>
        /// <param name="p_Value"></param>
        protected void WriteByte(byte p_Value, int p_StarIndex)
        {
            m_MemoryStraem.Position = p_StarIndex;
            m_MemoryStraem.WriteByte(p_Value);
        }
        /// <summary>
        /// 写入字节流
        /// </summary>
        /// <param name="p_Value"></param>
        /// <param name="p_StarIndex"></param>
        protected void WriteBytes(byte[] p_Value, int p_StarIndex)
        {
            m_MemoryStraem.Position = p_StarIndex;
            m_MemoryStraem.Write(p_Value, 0, p_Value.Length);
        }
        #endregion

        /// <summary>
        /// 更新消息头
        /// </summary>
        protected void UpdateHeard()
        {
            SGIP_SrcNodeSequence = 1;
            SGIP_DateSequence = (uint)(DateTime.Now.Month * 100000000 + DateTime.Now.Day * 1000000 + DateTime.Now.Hour * 10000 + DateTime.Now.Minute * 100 + DateTime.Now.Second);
            uint _Length = (uint)m_MemoryStraem.Length;
            WriteUint(_Length, 0);
        }

        public static SGIPCommand CreateCommand(MemoryStream p_Stream)
        {
            p_Stream.Position = 4;
            byte[] _Value = new byte[4];
            p_Stream.Read(_Value, 0, 4);
            Array.Reverse(_Value);
            Commands _Command = (Commands)BitConverter.ToUInt32(_Value, 0);
            switch (_Command)
            {
                case Commands.Bind:
                    return new BindCommand(p_Stream);
                case Commands.Bind_Resp:
                    return new BindRespCommand(p_Stream);
                case Commands.Deliver:
                    return new DeliverCommand(p_Stream);
                case Commands.Deliver_Resp:
                    return new DeliverRespCommand(p_Stream);
                case Commands.Submit:
                    return new SubmitCommand(p_Stream);
                case Commands.Submit_Resp:
                    return new SubmitRespCommand(p_Stream);
                case Commands.Report:
                    return new ReportCommand(p_Stream);
                case Commands.Report_Resp:
                    return new ReportRespCommand(p_Stream);
                case Commands.Unbind:
                    return new UnBindCommand(p_Stream);
                case Commands.Unbind_Resp:
                    return new UnBindRespCommand(p_Stream);
            }
            return null;
        }

        /// <summary>
        /// 命令类型
        /// </summary>
        public enum Commands : uint
        {
            Bind = 0x1,
            Bind_Resp = 0x80000001,
            Unbind = 0x2,
            Unbind_Resp = 0x80000002,
            Submit = 0x3,
            Submit_Resp = 0x80000003,
            Deliver = 0x4,
            Deliver_Resp = 0x80000004,
            Report = 0x5,
            Report_Resp = 0x80000005
        }
        /// <summary>
        /// 错误代码
        /// </summary>
        public enum ErrorCodes : byte
        {

            /// <summary>
            /// 0 无错误,命令正确接收
            /// </summary>
            Success = 0,
            /// <summary>
            /// 1 非法登录,如登录名、口令出错、登录名与口令不符等。
            /// </summary>
            LoginError = 1,
            /// <summary>
            /// 2 重复登录,如在同一TCP/IP连接中连续两次以上请求登录。
            /// </summary>
            Relogon = 2,
            /// <summary>
            /// 3 连接过多,指单个节点要求同时建立的连接数过多。
            /// </summary>
            ConnectionFull = 3,
            /// <summary>
            /// 4 登录类型错,指bind命令中的logintype字段出错。
            /// </summary>
            ErrorLoginType = 4,
            /// <summary>
            /// 5 参数格式错,指命令中参数值与参数类型不符或与协议规定的范围不符。
            /// </summary>
            ParameterError = 5,
            /// <summary>
            /// 6 非法手机号码,协议中所有手机号码字段出现非86130号码或手机号码前未加“86”时都应报错。
            /// </summary>
            TelnumberError = 6,
            /// <summary>
            /// 7 消息ID错
            /// </summary>
            MsgIDError = 7,
            /// <summary>
            /// 8 信息长度错
            /// </summary>
            PackageLengthError = 8,
            /// <summary>
            /// 9 非法序列号,包括序列号重复、序列号格式错误等
            /// </summary>
            SequenceError = 9,
            /// <summary>
            /// 10 非法操作GNS
            /// </summary>
            GnsOperationError = 10,
            /// <summary>
            /// 11 节点忙,指本节点存储队列满或其他原因,暂时不能提供服务的情况
            /// </summary>
            NodeBusy = 11,
            /// <summary>
            /// 21 目的地址不可达,指路由表存在路由且消息路由正确但被路由的节点暂时不能提供服务的情况
            /// </summary>
            NodeCanNotReachable = 21,
            /// <summary>
            /// 22 路由错,指路由表存在路由但消息路由出错的情况,如转错SMG等
            /// </summary>
            RouteError = 22,
            /// <summary>
            /// 23 路由不存在,指消息路由的节点在路由表中不存在
            /// </summary>
            RoutNodeNotExisted = 23,
            /// <summary>
            /// 24 计费号码无效,鉴权不成功时反馈的错误信息
            /// </summary>
            FeeNumberError = 24,
            /// <summary>
            /// 25 用户不能通信(如不在服务区、未开机等情况)
            /// </summary>
            UserCanNotReachable = 25,
            /// <summary>
            /// 26 手机内存不足
            /// </summary>
            HandsetFull = 26,
            /// <summary>
            /// 27 手机不支持短消息
            /// </summary>
            HandsetCanNotRecvSms = 27,
            /// <summary>
            /// 28 手机接收短消息出现错误
            /// </summary>
            HandsetReturnError = 28,
            /// <summary>
            /// 29 不知道的用户
            /// </summary>
            UnknownUser = 29,
            /// <summary>
            /// 30 不提供此功能
            /// </summary>
            NoDevice = 30,
            /// <summary>
            /// 31 非法设备
            /// </summary>
            InvalidateDevice = 31,
            /// <summary>
            /// 32 系统失败
            /// </summary>
            SystemError = 32,
            /// <summary>
            /// 33 短信中心队列满
            /// </summary>
            FullSequence = 33,
            /// <summary>
            /// 未知错误
            /// </summary>
            OtherError = 99,
        }

        public class BindCommand : SGIPCommand
        {
            /// <summary>
            /// 创建登陆
            /// </summary>
            /// <param name="p_User"></param>
            /// <param name="p_Command"></param>
            public BindCommand(string p_User, string p_PassWord, LoginTypes p_LongType)
            {
                base.Command = Commands.Bind;
                base.WriteByte((byte)p_LongType, 20);
                base.WriteString(p_User, 21, 16);
                base.WriteString(p_PassWord, 37, 16);
                base.WriteString("", 53, 8);
                base.UpdateHeard();
            }

            /// <summary>
            /// Bind操作,登录类型。
            /// </summary>
            public enum LoginTypes : byte
            {
                /// <summary>
                /// 1:SP向SMG建立的连接,用于发送命令
                /// </summary>
                SpToSmg = 1,
                /// <summary>
                /// 2:SMG向SP建立的连接,用于发送命令
                /// </summary>
                SmgToSp = 2,
                /// <summary>
                /// 3:SMG之间建立的连接,用于转发命令
                /// </summary>
                SmgToSmg = 3,
                /// <summary>
                /// 4:SMG向GNS建立的连接,用于路由表的检索和维护
                /// </summary>
                SmgToGns = 4,
                /// <summary>
                /// 5:GNS向SMG建立的连接,用于路由表的更新
                /// </summary>
                GnsToSmg = 5,
                /// <summary>
                /// 6:主备GNS之间建立的连接,用于主备路由表的一致性
                /// </summary>
                GnsToGns = 6,
                /// <summary>
                /// 11:SP与SMG以及SMG之间建立的测试连接,用于跟踪测试
                /// </summary>
                Test = 11,
                /// <summary>
                /// 其它:保留
                /// </summary>
                Unknown = 0
            }

            public BindCommand()
            {
            }
            public BindCommand(MemoryStream p_Stream)
            {
                base.m_MemoryStraem = p_Stream;
            }
        }

        public class UnBindCommand : SGIPCommand
        {
            public UnBindCommand()
            {
                base.Command = Commands.Unbind;
                base.UpdateHeard();
            }
        
            public UnBindCommand(MemoryStream p_Stream)
            {
                base.m_MemoryStraem = p_Stream;
            }
        }

        public class DeliverCommand : SGIPCommand
        {

            public DeliverCommand()
            {
                base.Command = Commands.Deliver;
                base.WriteString("", 20, 21);
                base.WriteString("", 41, 21);
                base.WriteByte((byte)0, 62);
                base.WriteByte((byte)0, 63);
                base.WriteByte((byte)m_MessageCoding, 64);
                base.WriteUint(0, 65);
                base.WriteString("", 69, 0);
                base.WriteString("", 69 + (int)MessageLength, 8);
                base.UpdateHeard();
            }

            public DeliverCommand(MemoryStream p_Stream)
            {
                base.m_MemoryStraem = p_Stream;
            }

            /// <summary>
            /// 短消息的编码格式
            /// </summary>
            private MessageCodings m_MessageCoding = MessageCodings.Gbk;

            /// <summary>
            /// 发送短消息的用户手机号,手机号码前加“86”国别标志,最大21位
            /// </summary>
            public string UserNumber { get { return base.ReadString(20, 21).Trim('/0'); } set { base.WriteString(value, 20, 21); } }
            /// <summary>
            /// SP接入号码  最大21位
            /// </summary>
            public string SPNumber { get { return base.ReadString(41, 21).Trim('/0'); } set { base.WriteString(value, 41, 21); } }
            /// <summary>
            /// GSM协议类型。详细解释请参考GSM03.40中的9.2.3.9 
            /// </summary>
            public byte TP_pid { get { return base.ReadByte(62); } set { base.WriteByte((byte)value, 62); } }
            /// <summary>
            /// GSM协议类型。详细解释请参考GSM03.40中的9.2.3.23,仅使用1位,右对齐
            /// </summary>
            public byte TP_udhi { get { return base.ReadByte(63); } set { base.WriteByte((byte)value, 63); } }
            /// <summary>
            /// 短消息的编码格式 重新设置 MessageContent 生效
            /// </summary>
            public MessageCodings MessageCoding { get { return m_MessageCoding; } set { m_MessageCoding = value; } }
            /// <summary>
            /// 短消息的长度
            /// </summary>
            public uint MessageLength { get { return base.ReadUint(65); } }
            /// <summary>
            /// 短消息的内容
            /// </summary>
            public string MessageContent
            {
                get
                {
                    int _BytesLength = (int)MessageLength;
                    string _Value = "";
                    switch (m_MessageCoding)
                    {
                        case MessageCodings.Gbk:
                            _Value = System.Text.Encoding.GetEncoding("unicodeFFFE").GetString(base.ReadBytes(69, _BytesLength));
                            return _Value;
                        case MessageCodings.Ascii:
                            _Value = System.Text.Encoding.ASCII.GetString(base.ReadBytes(69, _BytesLength));
                            break;
                    }
                    return _Value;
                }
                set
                {

                    byte[] _OldBytes = new byte[m_MemoryStraem.Length - 69 - (int)MessageLength];
                    m_MemoryStraem.Position = 69 + (int)MessageLength;
                    m_MemoryStraem.Read(_OldBytes, 0, _OldBytes.Length);
                    byte[] _ValueBytes = new byte[0];
                    switch (m_MessageCoding)
                    {
                        case MessageCodings.Gbk:
                            _ValueBytes = System.Text.Encoding.GetEncoding("Gbk").GetBytes(value);
                            base.WriteUint((uint)_ValueBytes.Length, 65);
                            base.WriteBytes(_ValueBytes, 69);
                            break;
                        case MessageCodings.Ascii:
                            _ValueBytes = System.Text.Encoding.ASCII.GetBytes(value);
                            base.WriteUint((uint)_ValueBytes.Length, 65);
                            base.WriteBytes(_ValueBytes, 69);
                            break;
                    }
                    m_MemoryStraem.Position = 69 + (int)MessageLength;
                    m_MemoryStraem.SetLength(m_MemoryStraem.Position);
                    m_MemoryStraem.Write(_OldBytes, 0, _OldBytes.Length);
                    base.UpdateHeard();
                }
            }

            /// <summary>
            /// 保留,扩展用
            /// </summary>
            public string Reserve { get { return base.ReadString(69 + (int)MessageLength, 8).Trim('/0'); } set { base.WriteString(value, 69 + (int)MessageLength, 8); } }


            /// <summary>
            /// 短消息的编码格式。
            /// </summary>
            public enum MessageCodings : byte
            {
                /// <summary>
                /// 0:纯ASCII字符串
                /// </summary>
                Ascii = 0,
                /// <summary>
                /// 3:写卡操作
                /// </summary>
                WriteCard = 3,
                /// <summary>
                /// 4:二进制编码
                /// </summary>
                Binary = 4,
                /// <summary>
                /// 8:UCS2编码
                /// </summary>
                Ucs2 = 8,
                /// <summary>
                /// 15: GBK编码
                /// </summary>
                Gbk = 15,
                /// <summary>
                /// 其它参见GSM3.38第4节:SMS Data Coding Scheme
                /// </summary>
                Others = 99,
            }
        }

        public class SubmitCommand : SGIPCommand
        {
            public SubmitCommand()
            {
                base.Command = Commands.Submit;
                base.WriteString("", 20, 21);
                base.WriteString("", 41, 21);
                base.WriteByte(0, 62);
                base.WriteString("", 63 + UserNumberSize, 5);
                base.WriteString("DCGZ", 68 + UserNumberSize, 10);
                base.WriteByte((byte)FeeTypes.Free, 78 + UserNumberSize);
                base.WriteString("0", 79 + UserNumberSize, 6);
                base.WriteString("0", 85 + UserNumberSize, 6);
                base.WriteByte((byte)SubmitAgentFlag.SouldIncome, 91 + UserNumberSize);
                base.WriteByte((byte)SubmitMorelatetoMTFlags.VoteFirst, 92 + UserNumberSize);
                base.WriteByte(0, 93 + (int)UserNumberSize);
                base.WriteString("", 94 + (int)UserNumberSize, 16);
                base.WriteString("", 110 + (int)UserNumberSize, 16);
                base.WriteByte((byte)SubmitReportFlag.ErrorReport, 126);
                base.WriteByte((byte)0, 127);
                base.WriteByte((byte)0, 128);
                base.WriteByte((byte)DeliverCommand.MessageCodings.Gbk, 129);
                base.WriteByte((byte)0, 130);
                base.WriteUint(0, 131);
                base.WriteString("", 135, 0);
                base.WriteString("", 135 + (int)MessageLength, 8);
                base.UpdateHeard();
            }

            public SubmitCommand(MemoryStream p_Stream)
            {
                base.m_MemoryStraem = p_Stream;
            }


            /// <summary>
            /// 短消息的编码格式
            /// </summary>
            private DeliverCommand.MessageCodings m_MessageCoding = DeliverCommand.MessageCodings.Gbk;
            /// <summary>
            /// 接收该短消息的手机大小
            /// </summary>
            private int UserNumberSize { get { return UserCount * 21; } }

            /// <summary>
            /// SP的接入号码
            /// </summary>
            public string SPNumber { get { return base.ReadString(20, 21).Trim('/0'); } set { base.WriteString(value, 20, 21); } }
            /// <summary>
            /// 付费号码,手机号码前加“86”国别标志;当且仅当群发且对用户收费时为空;如果为空,则该条短消息产生的费用由UserNumber代表的用户支付;如果为全零字符串“000000000000000000000”,表示该条短消息产生的费用由SP支付。
            /// </summary>
            public string ChargeNumber { get { return base.ReadString(41, 21).Trim('/0'); } set { base.WriteString(value, 41, 21); } }
            /// <summary>
            /// 接收短消息的手机数量,取值范围1至100
            /// </summary>
            public byte UserCount { get { return base.ReadByte(62); } }
            /// <summary>
            /// 接收该短消息的手机号,该字段重复UserCount指定的次数,手机号码前加“86”国别标志
            /// </summary>
            public List<string> UserNumber
            {
                get
                {
                    List<string> _ReturnList = new List<string>();
                    for (byte i = 0; i != UserCount; i++)
                    {
                        _ReturnList.Add(base.ReadString(63 + 21 * i, 21));
                    }
                    return _ReturnList;
                }
                set
                {
                    byte[] _OldBytes = new byte[m_MemoryStraem.Length - 63 - (21 * UserCount)];
                    m_MemoryStraem.Position = 63 + (21 * UserCount);
                    m_MemoryStraem.Read(_OldBytes, 0, _OldBytes.Length);

                    base.WriteByte((byte)value.Count, 62);

                    for (int i = 0; i != value.Count; i++)
                    {
                        base.WriteString(value[i], 63 + i * 21, 21);
                    }

                    m_MemoryStraem.Position = 63 + (21 * UserCount);
                    m_MemoryStraem.SetLength(m_MemoryStraem.Position);
                    m_MemoryStraem.Write(_OldBytes, 0, _OldBytes.Length);
                    base.UpdateHeard();
                }
            }
            /// <summary>
            /// 企业代码,取值范围0-99999
            /// </summary>
            public string CorpId { get { return base.ReadString(63 + UserNumberSize, 5).Trim('/0'); } set { base.WriteString(value, 63 + UserNumberSize, 5); } }
            /// <summary>
            /// 业务代码,由SP定义
            /// </summary>
            public string ServiceType { get { return base.ReadString(68 + UserNumberSize, 10).Trim('/0'); } set { base.WriteString(value, 68 + UserNumberSize, 10); } }
            /// <summary>
            /// 计费类型
            /// </summary>
            public FeeTypes FeeType { get { return (FeeTypes)base.ReadByte(78 + UserNumberSize); } set { base.WriteByte((byte)value, 78 + UserNumberSize); } }
            /// <summary>
            /// 取值范围0-99999,该条短消息的收费值,单位为分,由SP定义 对于包月制收费的用户,该值为月租费的值
            /// </summary>
            public string FeeValue { get { return base.ReadString(79 + UserNumberSize, 6).Trim('/0'); } set { base.WriteString(value, 79 + UserNumberSize, 6); } }
            /// <summary>
            /// 取值范围0-99999,赠送用户的话费,单位为分,由SP定义,特指由SP向用户发送广告时的赠送话费
            /// </summary>
            public string GivenValue { get { return base.ReadString(85 + UserNumberSize, 6).Trim('/0'); } set { base.WriteString(value, 85 + UserNumberSize, 6); } }
            /// <summary>
            /// 代收费标志,0:应收;1:实收
            /// </summary>
            public SubmitAgentFlag AgentFlag { get { return (SubmitAgentFlag)base.ReadByte(91 + UserNumberSize); } set { base.WriteByte((byte)value, 91 + UserNumberSize); } }
            /// <summary>
            /// 引起MT消息的原因0-MO点播引起的第一条MT消息;1-MO点播引起的非第一条MT消息;2-非MO点播引起的MT消息;3-系统反馈引起的MT消息。
            /// </summary>
            public SubmitMorelatetoMTFlags MorelatetoMTFlag { get { return (SubmitMorelatetoMTFlags)base.ReadByte(92 + UserNumberSize); } set { base.WriteByte((byte)value, 92 + UserNumberSize); } }
            /// <summary>
            /// 优先级0-9从低到高,默认为0
            /// </summary>
            public byte Priority { get { return base.ReadByte(93 + UserNumberSize); } set { base.WriteByte(value, 93 + UserNumberSize); } }
            /// <summary>
            /// 短消息寿命的终止时间,如果为空,表示使用短消息中心的缺省值。时间内容为16个字符,格式为”yymmddhhmmsstnnp” ,其中“tnnp”取固定值“032+”,即默认系统为北京时间
            /// </summary>
            public string ExpireTime { get { return base.ReadString(94 + UserNumberSize, 16).Trim('/0'); } set { base.WriteString(value, 94 + UserNumberSize, 16); } }
            /// <summary>
            /// 短消息定时发送的时间,如果为空,表示立刻发送该短消息。时间内容为16个字符,格式为“yymmddhhmmsstnnp” ,其中“tnnp”取固定值“032+”,即默认系统为北京时间
            /// </summary>
            public string ScheduleTime { get { return base.ReadString(110 + UserNumberSize, 16).Trim('/0'); } set { base.WriteString(value, 110 + UserNumberSize, 16); } }
            /// <summary>
            /// 状态报告标记
            /// </summary>
            public SubmitReportFlag ReportFlag { get { return (SubmitReportFlag)base.ReadByte(126 + UserNumberSize); } set { base.WriteByte((byte)value, 126 + UserNumberSize); } }
            /// <summary>
            /// GSM协议类型。详细解释请参考GSM03.40中的9.2.3.9 
            /// </summary>
            public byte TP_pid { get { return base.ReadByte(127 + UserNumberSize); } set { base.WriteByte((byte)0, 127 + UserNumberSize); } }
            /// <summary>
            /// GSM协议类型。详细解释请参考GSM03.40中的9.2.3.23,仅使用1位,右对齐
            /// </summary>
            public byte TP_udhi { get { return base.ReadByte(128 + UserNumberSize); } set { base.WriteByte((byte)0, 128 + UserNumberSize); } }
            /// <summary>
            /// 短消息的编码格式 重新设置 MessageContent 生效
            /// </summary>
            public DeliverCommand.MessageCodings MessageCoding { get { return m_MessageCoding; } set { m_MessageCoding = value; } }
            /// <summary>
            /// 信息类型:0-短消息信息其它:待定
            /// </summary>
            private byte MessageType { get { return base.ReadByte(130 + UserNumberSize); } set { base.WriteByte((byte)0, 130 + UserNumberSize); } }
            /// <summary>
            /// 短消息的长度
            /// </summary>
            public uint MessageLength { get { return base.ReadUint(131 + UserNumberSize); } }
            /// <summary>
            /// 短消息的内容
            /// </summary>
            public string MessageContent
            {
                get
                {
                    int _BytesLength = (int)MessageLength;
                    string _Value = "";
                    switch (m_MessageCoding)
                    {
                        case DeliverCommand.MessageCodings.Gbk:
                            _Value = System.Text.Encoding.GetEncoding("Gbk").GetString(base.ReadBytes(135 + UserNumberSize, _BytesLength));
                            return _Value;
                        case DeliverCommand.MessageCodings.Ascii:
                            _Value = System.Text.Encoding.ASCII.GetString(base.ReadBytes(135 + UserNumberSize, _BytesLength));
                            break;
                    }
                    return _Value;
                }
                set
                {

                    byte[] _OldBytes = new byte[m_MemoryStraem.Length - 135 - (int)MessageLength - UserNumberSize];
                    m_MemoryStraem.Position = 135 + UserNumberSize + (int)MessageLength;
                    m_MemoryStraem.Read(_OldBytes, 0, _OldBytes.Length);
                    byte[] _ValueBytes = new byte[0];
                    switch (m_MessageCoding)
                    {
                        case DeliverCommand.MessageCodings.Gbk:
                            _ValueBytes = System.Text.Encoding.GetEncoding("Gbk").GetBytes(value);
                            base.WriteUint((uint)_ValueBytes.Length, 131 + UserNumberSize);
                            base.WriteBytes(_ValueBytes, 135 + UserNumberSize);
                            break;
                        case DeliverCommand.MessageCodings.Ascii:
                            _ValueBytes = System.Text.Encoding.ASCII.GetBytes(value);
                            base.WriteUint((uint)_ValueBytes.Length, 131 + UserNumberSize);
                            base.WriteBytes(_ValueBytes, 135 + UserNumberSize);
                            break;
                    }
                    m_MemoryStraem.Position = 135 + (int)MessageLength + UserNumberSize;
                    m_MemoryStraem.SetLength(m_MemoryStraem.Position);
                    m_MemoryStraem.Write(_OldBytes, 0, _OldBytes.Length);
                    base.UpdateHeard();
                }
            }
            /// <summary>
            /// 保留,扩展用
            /// </summary>
            public string Reserve { get { return base.ReadString(135 + UserNumberSize + (int)MessageLength, 8).Trim('/0'); } set { base.WriteString(value, 135 + UserNumberSize + (int)MessageLength, 8); } }

            /// <summary>
            /// 计费类别定义
            /// </summary>
            public enum FeeTypes : byte
            {
                /// <summary>
                /// 0 “短消息类型”为“发送”,对“计费用户号码”不计信息费,此类话单仅用于核减SP对称的信道费
                /// </summary>
                FreeSend = 0,
                /// <summary>
                /// 1 对“计费用户号码”免费
                /// </summary>
                Free = 1,
                /// <summary>
                /// 2 对“计费用户号码”按条计信息费
                /// </summary>
                RowNumFee = 2,
                /// <summary>
                /// 3 对“计费用户号码”按包月收取信息费
                /// </summary>
                MonthFee = 3,
                /// <summary>
                /// 4 对“计费用户号码”的收费是由SP实现
                /// </summary>
                SpFee = 4,
            }
            /// <summary>
            /// 代收费标志,0:应收;1:实收
            /// </summary>
            public enum SubmitAgentFlag : byte
            {
                /// <summary>
                /// 0:应收
                /// </summary>
                SouldIncome = 0,
                /// <summary>
                /// 1:实收
                /// </summary>
                RealIncome = 1,
            }
            /// <summary>
            /// 引起MT消息的原因
            /// </summary>
            public enum SubmitMorelatetoMTFlags : byte
            {
                /// <summary>
                /// 0-MO点播引起的第一条MT消息;
                /// </summary>
                VoteFirst = 0,
                /// <summary>
                /// 1-MO点播引起的非第一条MT消息;
                /// </summary>
                VoteNonFirst = 1,
                /// <summary>
                /// 2-非MO点播引起的MT消息;
                /// </summary>
                NormalFirst = 2,
                /// <summary>
                /// 3-系统反馈引起的MT消息。
                /// </summary>
                NormalNonFirst = 3,
            }
            /// <summary>
            /// 状态报告标记
            /// </summary>
            public enum SubmitReportFlag : byte
            {
                /// <summary>
                /// 0-该条消息只有最后出错时要返回状态报告
                /// </summary>
                ErrorReport = 0,
                /// <summary>
                /// 1-该条消息无论最后是否成功都要返回状态报告
                /// </summary>
                Always = 1,
                /// <summary>
                /// 2-该条消息不需要返回状态报告
                /// </summary>
                NoReport = 2,
                /// <summary>
                /// 3-该条消息仅携带包月计费信息,不下发给用户,要返回状态报告
                /// </summary>
                MonthReport = 3,
            }
        }

        public class ReportCommand : SGIPCommand
        {
            public ReportCommand()
            {
                base.Command = Commands.Report;
                base.m_MemoryStraem.Write(new byte[36], 0, 36);
                base.UpdateHeard();
            }

            public ReportCommand(MemoryStream p_Stream)
            {
                base.m_MemoryStraem = p_Stream;
            }

            /// <summary>
            /// 该命令所涉及的Submit或deliver命令的序列号
            /// </summary>
            public uint SubmitSequenceNumber { get { return base.ReadUint(20); } set { base.WriteUint(value, 20); } }
            /// <summary>
            /// Report命令类型
            /// </summary>
            public ReportTypes ReportType { get { return (ReportTypes)base.ReadByte(32); } set { base.WriteByte((byte)value, 32); } }
            /// <summary>
            /// 接收短消息的手机号,手机号码前加“86”国别标志
            /// </summary>
            public string UserNumber { get { return base.ReadString(33, 21).Trim('/0'); } set { base.WriteString(value, 33, 21); } }
            /// <summary>
            /// 该命令所涉及的短消息的当前执行状态
            /// </summary>
            public ReportStates State { get { return (ReportStates)base.ReadByte(54); } set { base.WriteByte((byte)value, 54); } }
            /// <summary>
            /// 当State=2时为错误码值,否则为0
            /// </summary>
            public ErrorCodes ErrorCode { get { return (ErrorCodes)base.ReadByte(55); } set { base.WriteByte((byte)value, 55); } }
            /// <summary>
            /// 保留,扩展用
            /// </summary>
            public string Reserve { get { return base.ReadString(56, 8).Trim('/0'); } set { base.WriteString(value, 56, 8); } }

            /// <summary>
            /// Report命令类型
            /// </summary>
            public enum ReportTypes : byte
            {
                /// <summary>
                /// 0:对先前一条Submit命令的状态报告
                /// </summary>
                Submit = 0,
                /// <summary>
                /// 1:对先前一条前转Deliver命令的状态报告
                /// </summary>
                Deliver = 1,
            }

            /// <summary>
            /// 该命令所涉及的短消息的当前执行状态
            /// </summary>
            public enum ReportStates : byte
            {
                /// <summary>
                /// 0:发送成功
                /// </summary>
                Success = 0,
                /// <summary>
                /// 1:等待发送
                /// </summary>
                Accepted = 1,
                /// <summary>
                /// 2:发送失败
                /// </summary>
                Error = 2,
            }
        }

        public class BindRespCommand : SGIPCommand
        {
            public BindRespCommand()
            {
                base.Command = Commands.Bind_Resp;
                base.WriteString("", 21, 8);               
                base.UpdateHeard();
            }

            public BindRespCommand(MemoryStream p_Stream)
            {
                m_MemoryStraem = p_Stream;
            }

            /// <summary>
            /// 错误信息
            /// </summary>
            public ErrorCodes Error { get { return (ErrorCodes)ReadByte(20); } }

            public string Reserve { get { return ReadString(21, 8); } }

        }

        public class UnBindRespCommand : SGIPCommand
        {
            public UnBindRespCommand(MemoryStream p_Stream)
            {
                m_MemoryStraem = p_Stream;
            }
        }

        public class DeliverRespCommand : SGIPCommand
        {
            public DeliverRespCommand()
            {
                base.Command = Commands.Deliver_Resp;
                base.WriteString("", 21, 8);               
                base.UpdateHeard();
            }

            public DeliverRespCommand(MemoryStream p_Stream)
            {
                m_MemoryStraem = p_Stream;
            }
            /// <summary>
            /// 错误信息
            /// </summary>
            public ErrorCodes Error { get { return (ErrorCodes)ReadByte(20); } }

            public string Reserve { get { return ReadString(21, 8); } }
        }

        public class SubmitRespCommand : SGIPCommand
        {
            public SubmitRespCommand(MemoryStream p_Stream)
            {
                m_MemoryStraem = p_Stream;
            }
            /// <summary>
            /// 错误信息
            /// </summary>
            public ErrorCodes Error { get { return (ErrorCodes)ReadByte(20); } }

            public string Reserve { get { return ReadString(21, 8); } }
        }

        public class ReportRespCommand : SGIPCommand
        {
            public ReportRespCommand()
            {
                base.Command = Commands.Report_Resp;
                base.WriteString("", 21, 8);               
                base.UpdateHeard();
            }

            public ReportRespCommand(MemoryStream p_Stream)
            {
                m_MemoryStraem = p_Stream;
            }
            /// <summary>
            /// 错误信息
            /// </summary>
            public ErrorCodes Error { get { return (ErrorCodes)ReadByte(20); } }

            public string Reserve { get { return ReadString(21, 8); } }
        }

    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值