對網通必須使用兩個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); } }
}
}
}