最近要写 发短信的代码,哈哈一点心得,大家共享

1 以前以为只要掌握网管的api就可以免费收发短信了,实际是不可能的,不管是电信的小灵通还是移动 联通,接口都好找(api),但是你想过没 ,你的代码如果不放到电信或移动的网络中心 给你分配权限,你的短信如何能发出去,电信 或者 移动 要为你定制的业务分配权限和如何收费?

下面公开我的代码为以后写这方 面的兄弟提供方便,
电信 ->小灵通 ->SMGP协议
移动联通->通过第三方sp网管接口

1 我做的是个包 bpl ,由框架来调用
unit UnSMS;

interface

uses Classes, SysUtils, ExtCtrls, IniFiles, AdoDB, Contnrs, UnSMSDefine, UnOthSMSThread, UnLocSMSThread;

type
  TSMS = class(TInterfacedPersistent, ICallOutPlugin)
  private
    Timer: TTimer;
    OthThread: TOthSMSThread;
    LocThread: TLocSMSThread;
    sGID: String;
    EventResult: TEventResultCallBack;
    DBFuncCallBack: TDBFuncCallBack;
  protected
    procedure OnTestTimer(Sender: TObject);
    procedure Init(sGID: String; ReceiveEvent: TReceiveEventCallBack; EventResult: TEventResultCallBack; DBFuncCallBack: TDBFuncCallBack);
    procedure SendEvent(sGID: String; SendParams: array of variant);
    Destructor Destory;
    procedure ReturnErrorMsg(pInfo: ppInfo; iErrorID: Integer);
    function GetInfo(sInfo: String): String;
  public
end;

  function GetClassFromBPL: string;
exports
   GetClassFromBPL;

implementation

{ TSMS }

function GetClassFromBPL: string;
begin
  Result := 'TSMS';
end;

procedure TSMS.Init(sGID: String; ReceiveEvent: TReceiveEventCallBack; EventResult: TEventResultCallBack; DBFuncCallBack: TDBFuncCallBack);
begin
  try
    //**************
    Randomize;

    Timer := TTimer.Create(nil);
    Timer.Enabled := false;
    Timer.Interval := 5000;
    Timer.OnTimer := OnTestTimer;
    Timer.Enabled := true;

    //**************
    Self.sGID := sGID;
    Self.EventResult := EventResult;
    Self.DBFuncCallBack := DBFuncCallBack;

    LocThread := TLocSmsThread.Create(sGID, EventResult, DBFuncCallBack);
    OthThread := TOthSMSThread.Create(sGID, EventResult, DBFuncCallBack);           //创建两个单线程
  except
  end;
end;

procedure TSMS.SendEvent(sGID: String; SendParams: array of variant);
var
  i: Integer;
  Sql: String;
  pInfo: ppInfo;
  Query: TAdoQuery;
begin
  try
    try
      Self.sGID := sGID;
      if Length(SendParams) = 0 then Exit;
      if (SendParams[0] = '') or (SendParams[1] = '') or (SendParams[2] = '') or (SendParams[3] = '') then exit;
      if (SendParams[10] <> 0) and (now > SendParams[10]) then Exit;            //有效时间判断


      new(pInfo);
      pInfo.caller := SendParams[0];
      pInfo.callee := SendParams[1];
      pInfo.callinfo := GetInfo(SendParams[2]);
      pInfo.TaskID := SendParams[3];
      pInfo.SentTime := SendParams[9];
      pInfo.InvalidationTime := SendParams[10];

      Sql:= 'select dbo.PhoneType(' +#39+ SendParams[1] +#39+ ') ';
      Query := DBFuncCallBack(Sql, False, i);

      case Query.Fields[0].AsInteger of                                         //判断电话类别
       -1,0: begin
               ReturnErrorMsg(pInfo, Query.Fields[0].AsInteger);                //错误
               DisPose(pInfo);
               Exit;
             end;
        1: begin
             pInfo.callee := '028' + pInfo.callee;
             LocThread.AddTask(pInfo);                                          //小灵通
           end;
        2: begin                                                                //座机
             DisPose(pInfo);
             Exit;
           end;
        3: OthThread.AddTask(pInfo);                                            //手机
      end;
    finally
      FreeAndNil(Query);
    end;
  except
  end;
end;

destructor TSMS.Destory;
begin
  //**************
    Timer.Enabled := false;
    Timer.Free;
  //**************
  OthThread.Free;
  LocThread.Free;
  inherited;
end;

procedure TSMS.ReturnErrorMsg(pInfo: ppInfo; iErrorID: Integer);
var
  ResultParams: array of variant;
begin
  try
    SetLength(ResultParams, 14);
    ResultParams[0] := pInfo.caller;                                      //主叫
    ResultParams[1] := pInfo.callee;                                      //被叫
    ResultParams[2] := pInfo.callinfo;                                    //信息
    ResultParams[3] := pInfo.TaskID;
    case iErrorID of
      0: ResultParams[6] := '未知错误';
     -1: ResultParams[6] := '号码有误';
    end;
    ResultParams[7] := 0;
    ResultParams[9] := pInfo.SentTime;                                    //发送开始时间
    ResultParams[10] := pInfo.InvalidationTime;                           //发送截至时间
    EventResult(sGID, ResultParams);
  except
  end;
end;

procedure TSMS.OnTestTimer(Sender: TObject);     //测试
var
  testParams: array of variant;
begin
  TTimer(Sender).Enabled := false;
  SetLength(testParams, 14);
  testParams[0] := '1234';
  //testParams[1] := '8804286'+ IntToStr(Random(9));
  testParams[1] := '81900777';
  testParams[2] := '你好,<用户>罗俊</用户>向你发起看病请求,基本信息<年龄>21</年龄>,<文化程度>小学</文化程度>';
  testParams[3] := IntToStr(Random(1000));
  testParams[9] := now;
  testParams[10] := 0;
  SendEvent('12343DFGDSF-324DG3G-324GFG3G4G4-GRT5434R532-2343FFF434', testParams);
  //TTimer(Sender).Enabled := true;
end;

function TSMS.GetInfo(sInfo: String): String;
var
  i, j: Integer;
begin
  Result := sInfo;
  repeat
    i := pos('<', Result);
    if i > 0 then
    begin
      Delete(Result, i, 1);
      j := pos('>', Result);
      Delete(Result, j, 1);
    end;
    i := pos('</', Result);
    if i > 0 then
    begin
      j := pos('>', Result);
      j := j - i + 1;
      Delete(Result, i, j);
    end;
  until i = 0;
end;

initialization
  RegisterClass(TSMS);

finalization
  UnRegisterClass(TSMS);
end.

2 接口文件
unit UnSMSDefine;

interface

uses Variants, ADODB, Contnrs, Windows;

ResourceString
  sQuery           = 'Select * from %s where %s = '+#39+'%s'+#39;
  sInsertErronInfo = ' insert into ErrorInfo ( Name ) values ( '+#39+'%s'+#39+' )';

  sHttpGW = 'http://intra.qianet.com/public/MtFromSFGS.php?mobile=%s&phone=%s&msg=%s'; //SP网关地址

  sSmsLog = 'insert into SmSLog (Caller, Callee, Message, Flag, ErrorID, OccurDate, NetFlag)'+
            ' values('+#39+'%s'+#39+','+#39+'%s'+#39+','+#39+'%s'+#39+','+
            #39+'%s'+#39+','+'%s'+','+#39+'%s'+#39+','+#39+'%s'+#39+  ')';

const cDefineTime = 300000;                                                       //预定义查询时间为5分钟

type
  TGetClassFromBPL = function: String;
  TDBFuncCallBack = function(Sql: String; ExecFlag: Boolean; var ChangeCount: Integer): TADOQuery of object;
  TEventResultCallBack = procedure(sGID:string;ResultParams:array of variant) of object;
  TReceiveEventCallBack = procedure(sGID:string;ReceiveParams:array of variant) of object;

  ICallOutPlugin = interface
  ['{A0B40DA3-F9FF-45EE-896D-B32570ABFC07}']
    procedure Init(sGID: String;ReceiveEvent: TReceiveEventCallBack; EventResult: TEventResultCallBack; DBFuncCallBack: TDBFuncCallBack);
    procedure SendEvent(sGID: String;SendParams: array of variant);
 end;

  PDeliverResp = ^TDeliverResp; 
  TDeliverResp = packed Record
    //SmsgID: TBcd;
    SmsgID: array [1..11]of Char;                   //短消息标识
    NmsgFormat:integer;                             //短消息格式(参照短消息格式代码表)。网关不做判定, 透明传输
    SsrcTermID:array [1..22]of char;                //短消息发送用户号码
    NisReport,                                      //是否状态报告。代码含义:非状态报告0;是状态报告1
    NmsgLen:integer;                                //消息长度
    sMsgContent:array [1..201]of char;              //消息内容(若消息为状态报告则为状态报告内容)
    sDestTermID:array [1..21]of char;               // CP的接入代码
    sRecvTime:array [1..15]of char;                 //短消息接收时间
  end;

  ppInfo = ^TInfo;
  TInfo = record
    TaskID: String[140];
    caller: String;
    callee: String;
    CallerType: Byte;
    SentTime: TDateTime;
    InvalidationTime: TDateTime;
    callinfo: String;
  end;
 
  // SMSLOG NetFalg bit 0:本网  1:异网

  function InitSMGPAPI(pIniFile: String): DWORD; stdcall; external 'SmgpDll.dll';

  function SMGPSendSingle(   nNeedReport,          //是否要求返回状态报告(0=不要求,1=要求)
                           nMsgLevel: Integer;     //优先级别,(0-9,0表示最低优先级)
                           sServiceID: PChar;      //业务类型
                           nMsgFormat: Integer;    //短消息格式(参照附录短消息格式表)网关不做判定, 透明传输
                             sFeeType,             //资费类别,参照附录短消息参数表
                           sFeeCode,               //资费代码(以分为单位)
                           sFixedFee,              //包月费/封顶费(以分为单位)
                           sValidTime,             //存活有效期,格式遵循SMPP3.3协议
                           sAtTime,                //定时发送时间,格式遵循SMPP3.3协议
                           sChargeTermID,          //计费号码
                           sDestTermID: PChar;     //短消息接收号码
                           nMsgLen:Integer;        //消息长度
                           sMsgContent: PChar;     //短消息内容(nMsgLen=0时表示存放短消息的文件名)
                           sMsgID: pchar;          // PChar;返回的短消息标识
                           out pnErrorCode: int64;  //错误代码(参照附录错误代码表)
                           nMsgType: Integer;      //短消息类型,参照附录短消息参数表
                           sSrcTermID: PChar): DWORD; StdCall; External 'SmgpDll.dll';  //短消息发送号码。

  function SMGPDeliver(nTimeout: Integer; out DeliverResp: TDeliverResp): Dword; StdCall; External 'SmgpDll.dll';

  function CMPPActiveTest(dwRetry:Integer): Integer; StdCall; External 'SmgpDll.dll';

  function SMGPDisconnect():Integer; Stdcall; External 'SmgpDll.dll';

implementation

{
  RP[0]:=RegisterPhone;    //主叫计费号码      1
  RP[1]:=TargetAddr;       //发送地址          1
  RP[2]:=Info;             //发送信息          1
  RP[3]:=UserlogID;        //日志ID            1   taskid
  RP[4]:=SCID;             //服务公司ID
  RP[5]:=CommunityID;      //所属社区ID
  RP[6]:=StatusDesc;       //状态描述          2
  RP[7]:=Status;           //状态值            2          int
  RP[8]:=SendIFID;         //发送类型ID
  RP[9]:=StartTime;        //发送开始时间      1          TDatetime
  RP[10]:=InvalidationTime;//发送截至时间      1          TDatetime
  RP[11]:=UserID;          //外呼的发起者ID  HHID(管理员ID)
  RP[12]:=BackIFID;        //回送显示的发送类型ID
  RP[13]:=BackTargetAddr;  //回送显示的发送类型地址
 }
end.

3 电信小灵通线程发短信
unit UnLocSMSThread;

interface

uses Classes, Windows, SysUtils, ADODB, UnSMSDefine;

type
  TLocSMSThread = class(TThread)
  private
    sErrorID,
    sErrorInfo: String;
    iResultMsg: Integer;
    pInfo: ppInfo;
    List: TList;
    ThreadList: TThreadList;
    sGID: String;
    EventResult: TEventResultCallBack;
    DBFuncCallBack: TDBFuncCallBack;
    procedure SentSMS;
    procedure SMGPMsg;
    procedure WriteLog;
    function GetGUID: String;
    procedure ReturnMsg;

    procedure SyncWriteLog;
    procedure SyncGetGUID;
    procedure SyncReturnMsg;
  protected
    procedure Execute; override;
  public
    procedure AddTask(pInfo: ppInfo);
    Constructor Create(sGID: String; EventResult: TEventResultCallBack; DBFuncCallBack: TDBFuncCallBack);
    destructor Destroy; override;
  end;
implementation

{ TLocSMSThread }

constructor TLocSMSThread.Create(sGID: String; EventResult: TEventResultCallBack; DBFuncCallBack: TDBFuncCallBack);
begin
  sErrorInfo := '';
  iResultMsg := -1;
  List := TList.Create;
  ThreadList := TThreadList.Create;
  Self.sGID := sGID;
  Self.EventResult := EventResult;
  Self.DBFuncCallBack := DBFuncCallBack;

  InitSMGPAPI('./smgpc.ini');
  inherited Create(False);
end;

procedure TLocSMSThread.Execute;
begin
  FreeOnTerminate := true;
  SentSMS;
end;

procedure TLocSMSThread.SentSMS;
begin
  try
    while true do
    begin
      Sleep(1);
      List := ThreadList.LockList;
      if List.Count = 0 then
      begin
        ThreadList.UnlockList;
        //suspend;
        Continue;
      end;

      pInfo := List[0];
      List.Delete(0);
      ThreadList.UnlockList;

      SMGPMsg;
      Synchronize(SyncReturnMsg);                                    //发消息给后台调度
      Synchronize(SyncWriteLog);                                                           //写日志
      DisPose(pInfo);
    end;
  except
  end;
end;

procedure TLocSMSThread.WriteLog;
var
  i: integer;
  sFalg, sOccurDate, Sql: String;
begin
  try
    if not Assigned(pInfo) then Exit; //wy
    sOccurDate := FormatDateTime('yyyy-mm-dd hh:mm:ss', pInfo.SentTime);

    case iResultMsg of
      0:
        begin
          sErrorID := 'NULL';
          sFalg := '1';
        end;
      else
        begin
          sFalg := '0';
          sErrorInfo := '';
          case iResultMsg of
            4:  sErrorInfo := '法短消息长度' ;
            5:    sErrorInfo := '非法资费代码'  ;
            6:    sErrorInfo := '短消息长度超长' ;
            7:    sErrorInfo := '非法业务类型' ;
            8:    sErrorInfo := '短消息发送速度太快' ;
            10:    sErrorInfo := '非法CP编号' ;
            11:    sErrorInfo := '非法信息格式' ;
            12:    sErrorInfo := '非法资费类别' ;
            13:    sErrorInfo := '非法存活有效期' ;
            14:    sErrorInfo := '非法定时发送时间' ;
            15:    sErrorInfo := '非法计费号码' ;
            16:    sErrorInfo := '非法目标号码' ;
            17:    sErrorInfo := '不能打开目标号码文件' ;
            18:    sErrorInfo := '不能打开短消息内容文件' ;
            19:    sErrorInfo := '非法短消息' ;
            20:    sErrorInfo := '连接短消息网关失败' ;
            21:    sErrorInfo := '登录失败' ;
            22:    sErrorInfo := '接收结果数据包失败' ;
            23:    sErrorInfo := '发送队列满' ;
            24:    sErrorInfo := '超出系统限制' ;
            25:    sErrorInfo := '系统忙' ;
            26:    sErrorInfo := '超过最大连接数' ;
            27:    sErrorInfo := '消息结构错' ;
            28:    sErrorInfo := '命令字错' ;
            29:    sErrorInfo := '序列号重复' ;
            30:    sErrorInfo := 'IP地址错' ;
            31:    sErrorInfo := '认证错' ;
            32:    sErrorInfo := '版本太高' ;
            33:    sErrorInfo := '非法消息类型' ;
            34:    sErrorInfo := '非法优先级' ;
            35:    sErrorInfo := '非法时间格式' ;
            36:    sErrorInfo := '有效期已过' ;
            37:    sErrorInfo := '路由错误' ;
            94:    sErrorInfo := '非法状态报告要求标志' ;
            95:    sErrorInfo := '非法包月/封顶费' ;
            96:    sErrorInfo := '等待回应数据包超时' ;
            97:    sErrorInfo := '发送数据包失败' ;
            98:    sErrorInfo := '非法短消息发送号码' ;
            99:    sErrorInfo := '系统错误' ;
          end;
          Synchronize(SyncGetGUID);
        end;
    end;
    Sql := Format(sSmsLOg,[pInfo.caller, pInfo.callee, pInfo.callinfo, sFalg, sErrorID, sOccurDate, '0']);
    DBFuncCallBack(Sql, True, i);
  except
  end;
end;

procedure TLocSMSThread.ReturnMsg;
var
  ResultParams: array of variant;
begin
  try
    if not Assigned(pInfo) then Exit;

    SetLength(ResultParams, 14);
    ResultParams[0] := pInfo.caller;                                      //主叫
    ResultParams[1] := pInfo.callee;                                      //被叫
    ResultParams[2] := pInfo.callinfo;                                    //信息
    ResultParams[3] := pInfo.TaskID;                                      //任务号

    case iResultMsg of
      4:  ResultParams[6] := '法短消息长度';
      5:    ResultParams[6] := '非法资费代码' ;
      6:    ResultParams[6] := '短消息长度超长';
      7:    ResultParams[6] := '非法业务类型';
      8:    ResultParams[6] := '短消息发送速度太快';
      10:    ResultParams[6] := '非法CP编号';
      11:    ResultParams[6] := '非法信息格式';
      12:    ResultParams[6] := '非法资费类别';
      13:    ResultParams[6] := '非法存活有效期';
      14:    ResultParams[6] := '非法定时发送时间';
      15:    ResultParams[6] := '非法计费号码';
      16:    ResultParams[6] := '非法目标号码';
      17:    ResultParams[6] := '不能打开目标号码文件';
      18:    ResultParams[6] := '不能打开短消息内容文件';
      19:    ResultParams[6] := '非法短消息';
      20:    ResultParams[6] := '连接短消息网关失败';
      21:    ResultParams[6] := '登录失败';
      22:    ResultParams[6] := '接收结果数据包失败';
      23:    ResultParams[6] := '发送队列满';
      24:    ResultParams[6] := '超出系统限制';
      25:    ResultParams[6] := '系统忙';
      26:    ResultParams[6] := '超过最大连接数';
      27:    ResultParams[6] := '消息结构错';
      28:    ResultParams[6] := '命令字错';
      29:    ResultParams[6] := '序列号重复';
      30:    ResultParams[6] := 'IP地址错';
      31:    ResultParams[6] := '认证错';
      32:    ResultParams[6] := '版本太高';
      33:    ResultParams[6] := '非法消息类型';
      34:    ResultParams[6] := '非法优先级';
      35:    ResultParams[6] := '非法时间格式';
      36:    ResultParams[6] := '有效期已过';
      37:    ResultParams[6] := '路由错误';
      94:    ResultParams[6] := '非法状态报告要求标志';
      95:    ResultParams[6] := '非法包月/封顶费';
      96:    ResultParams[6] := '等待回应数据包超时';
      97:    ResultParams[6] := '发送数据包失败';
      98:    ResultParams[6] := '非法短消息发送号码';
      99:    ResultParams[6] := '系统错误';
    end;

    case iResultMsg of                                    //转换为后台调度中心能识别的
      0: ResultParams[7] := 1;
    else
      ResultParams[7] := 0;
    end;
    ResultParams[9] := pInfo.SentTime;                                    //发送开始时间
    ResultParams[10] := pInfo.InvalidationTime;                           //发送截至时间

    EventResult(sGID,ResultParams);
  except
  end;
end;

procedure TLocSMSThread.AddTask(pInfo: ppInfo);
begin
  ThreadList.Add(pInfo);
  //resume;
end;

destructor TLocSMSThread.Destroy;
begin
  SMGPDisconnect;
  ThreadList.Free;
  List.Free;
  inherited;
end;

function TLocSMSThread.GetGUID: String;
  function GetInfo(sErrorInfo: String): TAdoQuery;
  var
    i: Integer;
    Sql: String;
  begin
    Result := nil;
    Sql := Format(sQuery, ['ErrorInfo', 'Name', sErrorInfo]);
    Result := DBFuncCallBack(Sql, False, i);
  end;
var
  Query: TAdoQuery;
  i: Integer;
  Sql: String;
begin
  Result := 'Null';
  try
    try
      Query := GetInfo(sErrorInfo);
      if Query.IsEmpty then
      begin
        Sql := Format(sInsertErronInfo, [sErrorInfo]);
        DBFuncCallBack(Sql, True, i);
        Query := GetInfo(sErrorInfo);
      end;
      Result := #39+ Query.FieldByName('_ID').AsString +#39;
    finally
      FreeAndNil(Query);
    end;
  except
  end;
end;

procedure TLocSMSThread.SyncGetGUID;
begin
  sErrorID := GetGUID;
end;

procedure TLocSMSThread.SyncReturnMsg;
begin
  ReturnMsg;
end;

procedure TLocSMSThread.SyncWriteLog;
begin
  WriteLog;
end;

procedure TLocSMSThread.SMGPMsg;
var
  iErrorCode: Int64;
  sMsgId: array[0..300] of char;
  i: Integer;
begin
  i := -1;
  try
    if not Assigned(pInfo) then Exit; //wy

    CMPPActiveTest(1);
    i := SMGPSendSingle(
                        0,
                        1,
                        '900004',
                        15,
                        '00',
                        '000000',
                        '000000',
                        '',
                        '',
                        PChar(pInfo.caller),
                        PChar(pInfo.callee),
                        Length(pInfo.callinfo),
                        PChar(pInfo.callinfo),
                        sMsgId,
                        iErrorCode,
                        3,
                        PChar(pInfo.caller)
                        );
    case i of
      0: iResultMsg := 0;
      1: iResultMsg := iErrorCode;
    end;
  except
  end;
end;


end.

4 移动联通 通过第三方网管发送短信
unit UnOthSMSThread;

interface

uses Classes, Windows, Messages, IdHTTP, SysUtils, ADODB, UnSMSDefine;

type
  TOthSMSThread = class(TThread)
  private
    iResultMsg: Integer;
    sHttp,
    sErrorID,
    sErrorInfo: String;
    pInfo: ppInfo;
    List: TList;
    ThreadList: TThreadList;
    sGID: String;
    EventResult: TEventResultCallBack;
    DBFuncCallBack: TDBFuncCallBack;
    procedure SentSMS;
    procedure WriteLog;
    function GetGUID(sErrorInfo: String): String;
    procedure Get(sHttp: String);
    procedure ReturnMsg;

    procedure SyncWriteLog;
    procedure SyncGetGUID;
    procedure SyncReturnMsg;
  protected
    procedure Execute; override;
  public
    procedure AddTask(pInfo: ppInfo);
    Constructor Create(sGID: String; EventResult: TEventResultCallBack; DBFuncCallBack: TDBFuncCallBack);
    Destructor Destroy; override;
  end;
implementation

{ TOthSMSThread }

procedure TOthSMSThread.Get(sHttp: String);
var
  IDHttp: TIDHttp;
  sMsg: String;
begin
  IDHttp := TIDHttp.Create(nil);
  try
    try
      IDHttp.Request.ContentType := 'application/x-www-form-urlencoded';
      IDHttp.HandleRedirects := true;                                     //必须支持重定向否则可能出错
      IDHttp.ReadTimeout := 10000;                                        //超过这个时间则不再访问,单线程延迟1秒
      sMsg := IDHttp.Get(sHttp);                                          //
      if IDHttp.ResponseCode = 200 then
        iResultMsg := StrToInt(sMsg);
    except
    end;
  finally
    iResultMsg := -1;
    IDHttp.Free;
  end;
end;

constructor TOthSMSThread.Create(sGID: String; EventResult: TEventResultCallBack; DBFuncCallBack: TDBFuncCallBack);
begin
  List := TList.Create;
  ThreadList := TThreadList.Create;
  Self.sGID := sGID;
  Self.EventResult := EventResult;
  Self.DBFuncCallBack := DBFuncCallBack;
  inherited Create(False);
end;

procedure TOthSMSThread.Execute;
begin
  FreeOnTerminate := true;
  SentSMS;
end;

procedure TOthSMSThread.SentSMS;
begin
  try
    while true do
    begin
      Sleep(1);
      List := ThreadList.LockList;
      if List.Count = 0 then
      begin
        ThreadList.UnlockList;
        Continue;
      end;

      pInfo := List[0];
      List.Delete(0);
      ThreadList.UnlockList;
      sHttp := Format(sHttpGW,[pInfo.callee, pInfo.caller, pInfo.callinfo]);
      Get(sHttp);
      Synchronize(SyncReturnMsg);                                               //发消息给后台调度
      Synchronize(SyncWriteLog);                                                //写日志
    end;
  except
  end;
end;

procedure TOthSMSThread.WriteLog;
var
  i: integer;
  sFalg, sOccurDate, Sql: String;
begin
  try
    if not Assigned(pInfo) then Exit; //wy
    sOccurDate := FormatDateTime('yyyy-mm-dd hh:mm:ss', pInfo.SentTime);

    case iResultMsg of
      0:
        begin
          sErrorID := 'Null';                                                     //错误id
          sFalg := '1';
        end;
      else
      begin
        sFalg := '0';
        case iResultMsg of
          1: sErrorInfo := 'SP网关服务端内部设置错误';
          2: sErrorInfo := 'SP网关IP禁止,即访问此URL的IP地址非法';
          3: sErrorInfo := 'SP网关解析被叫号码为空';
          4: sErrorInfo := 'SP网关解析主叫号码为空';
          5: sErrorInfo := 'SP网关解析短信内容为空';
          6: sErrorInfo := 'SP网关数据库错误';
         -1: sErrorInfo := '与短信网关联系失败';
        end;
        Synchronize(SyncGetGUID);
      end;
    end;
    Sql := Format(sSmsLOg,[pInfo.caller, pInfo.callee, pInfo.callinfo, sFalg, sErrorID, sOccurDate, '1']);
    DBFuncCallBack(Sql, True, i);
  except
  end;
end;

procedure TOthSMSThread.ReturnMsg;
var
  ResultParams: array of variant;
begin
  try
    if not Assigned(pInfo) then Exit; //wy
    SetLength(ResultParams, 14);
    ResultParams[0] := pInfo.caller;                                      //主叫
    ResultParams[1] := pInfo.callee;                                      //被叫
    ResultParams[2] := pInfo.callinfo;                                    //信息
    ResultParams[3] := pInfo.TaskID;                                      //任务号

    case iResultMsg of
      0: ResultParams[6] := '成功';
      1: ResultParams[6] := '服务端内部设置错误';
      2: ResultParams[6] := 'IP禁止,即访问此URL的IP地址非法';
      3: ResultParams[6] := '被叫号码为空';
      4: ResultParams[6] := '主叫号码为空';
      5: ResultParams[6] := '短信内容为空';
      6: ResultParams[6] := '数据库错误';
      -1: ResultParams[6] := '与短信网关联系失败';
    end;

    case iResultMsg of                                    //转换为后台调度中心能识别的
      0: ResultParams[7] := 0;
    else
      ResultParams[7] := 1;
    end;

    ResultParams[9] := pInfo.SentTime;                                    //发送开始时间
    ResultParams[10] := pInfo.InvalidationTime;                           //发送截至时间

    EventResult(sGID,ResultParams);
  except
  end;
end;


procedure TOthSMSThread.AddTask(pInfo: ppInfo);
begin
  ThreadList.Add(pInfo);
end;

destructor TOthSMSThread.Destroy;
begin
  ThreadList.Free;
  List.Free;
  inherited;
end;

function TOthSMSThread.GetGUID(sErrorInfo: String): String;
  function GetInfo(sErrorInfo: String): TAdoQuery;
  var
    i: Integer;
    Sql: String;
  begin
    Result := nil;
    Sql := Format(sQuery, ['ErrorInfo', 'Name', sErrorInfo]);
    Result := DBFuncCallBack(Sql, False, i);
  end;
var
  Query: TAdoQuery;
  i: Integer;
  Sql: String;
begin
  Result := 'null';
  try
    try
      Query := GetInfo(sErrorInfo);
      if Query.IsEmpty then
      begin
        Sql := Format(sInsertErronInfo, [sErrorInfo]);
        DBFuncCallBack(Sql, True, i);
        Query := GetInfo(sErrorInfo);
      end;
      Result := #39+ Query.FieldByName('_ID').AsString +#39;
    finally
      FreeAndNil(Query);
    end;
  except
  end;
end;

procedure TOthSMSThread.SyncGetGUID;
begin
  sErrorID := GetGUID(sErrorInfo);
end;

procedure TOthSMSThread.SyncReturnMsg;
begin
  ReturnMsg;
end;


procedure TOthSMSThread.SyncWriteLog;
begin
  WriteLog;
end;

end.

 

AT指令收发短信,需要短信猫的支持 /// <summary> /// 针对国内短信编码(USC2) /// </summary> public class USC2 { public readonly static int MAX_CHAR_COUNT = 70;//最长可发送汉字个数 /**/ /// <summary> /// 奇偶互换并补F /// </summary> /// <param name="value"></param> /// <returns></returns> private static string ParityChange(string value) { string result = string.Empty; int length = value.Length; for (int i = 1; i < length; i += 2)//奇偶互换 { result += value[i]; result += value[i - 1]; } if (!(length % 2 == 0))//不是偶数则加上F,与最后一位互换 { result += 'F'; result += value[length - 1]; } return result; } /**/ /// <summary> /// 短信内容编码 /// </summary> /// <param name="value"></param> /// <returns></returns> /// <remarks> /// 采用Big-Endian 字节顺序的 Unicode 格式编码,将高低位互换 /// 将转换后的短信内容存进字节数组 /// 去掉在进行Unicode格式编码中,两个字节中的"-",例如:00-21,变成0021 /// 将整条短信内容的长度除2,保留两位16进制数 /// </remarks> public static string Encoding(string value) { Encoding encoding = System.Text.Encoding.BigEndianUnicode; string result = string.Empty; byte[] bytes = encoding.GetBytes(value); for (int i = 0; i < bytes.Length; i++) { result += BitConverter.ToString(bytes, i, 1); } return result; } public static string EncodeingAddLength(string value) { string result = Encoding(value); return String.Format("{0:X2}{1}", result.Length / 2, result); } /**/ /// <summary> /// 短信中号码编码 /// </summary> /// <param name="value"></param> /// <returns></returns> public static string DecodingCenter(string phone) { string result = string.Empty; result = ParityChange(phone); result = String.Format("91{0}", result);//加上91 result = String.Format("{0:X2}{1}", result.Length / 2, result); return result; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值