短信相关的小例子
type TsmsPDU = packed record
SCAL: string; //SMSC地址信息的长度
SCAT: string; //SMSC地址格式(TON/NPI)
SCA: string; //SMSC地址
TP_BR: string; //基本参数(发送:TP_MTI/VFP 接收:TP_MTI/MMS/RP)
TP_MR: string; //消息基准值(TP_MR)
TP_AL: string; //目标/回复地址数字个数
TP_AT: string; //目标/回复地址格式(TON/NPI)
TP_AD: string; //目标/回复地址
TP_PID: string; //协议标识
TP_DCS: string; //用户信息编码方式
TP_VP: string; //有效期
TP_SCTS:string; //时间戳
TP_UDL: string; //用户信息长度
TP_UD: string; //用户信息
PDUL: string; //CMGS字符串长度值
PDU: string; //要发送的PDU串
INDEX: Integer; //接收的短消息序号
STATE: Integer; //短消息的状态 0=unread 1=read 2=unsend 3=send 4=all
end;
var smsSendPDU: TsmsPDU;
procedure TForm.Wait(milliseconds: Cardinal);
var
starttime:cardinal;
begin
starttime := GetTickCount;
while (GetTickCount - starttime) < milliseconds do
begin
Sleep(50);
Application.ProcessMessages;
end;
end;
function HexToStr(str:string):string;
var i:integer;
s:string;
begin
i:=1;
while i<length(str) do
begin
s:=str[i]+str[i+1];
result := result + chr(ord(strtoint('$'+s)));
inc(i,2);
end;
end;
//将字符串每隔两位将前后位互换,末位是奇数位用F补足再互换(PDU短信格式)
function sms_InvertNumbers(const Src: string; var Dst: string):Integer;
var
DstLength: Integer; // 目标字符串长度
AChar: Char; // 用于保存一个字符
I: Integer;
begin
Dst := EmptyStr;
I := 1;
while I < Length(Src) do
begin
Dst := Dst + Src[I+1] + Src[I];
Inc(I,2);
end;
if Length(Src) mod 2 <> 0 then
begin
Dst := Dst + 'F' + Src[Length(Src)];
end;
//if Dst[Length(Dst)-1] = 'F' then
// Result := Length(Dst) - 1
//else
Result := Length(Dst);
end;
//将每两位互换的字符串转换为正常顺序字符串(PDU短信格式)
function sms_SerialNumbers(const Src: string; var Dst: string): Integer;
var
DstLength: Integer; // 目标字符串长度
I: Integer;
begin
Dst := EmptyStr;
I := 1;
while I < Length(Src) do
begin
Dst := Dst + Src[I+1] + Src[I];
Inc(I,2);
end;
if Src[Length(Src)] = 'F' then
begin
Delete(Dst, Length(Src)-1, 1);
end;
//if Dst[Length(Dst)-1] = 'F' then
// Result := Length(Dst) - 1
//else
Result := Length(Dst);
end;
//将短信内容转换为Unicode类型(PDU格式)
function sms_AnsiToUnicode(const Source: string; var Dest: String):Integer;
var
UniStr: WideString;
S: String;
i: Integer;
begin
UniStr := Source;
for i := 1 to Length(UniStr) do
begin
S := IntToHex(WORD(UniStr[i]),4);
Dest := Dest + S;
end;
Result := Length(Dest) div 2;
end;
//将Unicode格式转换为短信内容(PDU格式)
function sms_UnicodeToAnsi(const Source: string; var Dest: widestring): Integer;
var
AnsiStr: ansistring;
s: string;
i:Integer;
begin
AnsiStr := Source;
for i := 1 to Length(AnsiStr) do
begin
s := Copy(AnsiStr, i*4-3,4);
if s ='' then break;
s := Format('%d', [strtoint('$' + s)]);
Dest := Dest + wideChar(strtoint(s));
end;
end;
//function sms_EncodePDU(var _smsPDU: TsmsPDU; DstCode:string; DCS:Integer; VP:Integer; UD:string): Boolean;
//function sms_EncodePDU(var _smsPDU: TsmsPDU; DstCode:string; DCS: Integer; UD:string): Boolean;
function sms_EncodePDU(var _smsPDU: TsmsPDU; DstCode:string; UD:string): Boolean;
begin
_smsPDU.SCAL := EmptyStr;
_smsPDU.SCAT := EmptyStr;
_smsPDU.SCA := EmptyStr;
_smsPDU.TP_BR := EmptyStr;
_smsPDU.TP_MR := EmptyStr;
_smsPDU.TP_AL := EmptyStr;
_smsPDU.TP_AT := EmptyStr;
_smsPDU.TP_AD := EmptyStr;
_smsPDU.TP_PID := EmptyStr;
_smsPDU.TP_DCS := EmptyStr;
_smsPDU.TP_VP := EmptyStr;
_smsPDU.TP_SCTS := EmptyStr;
_smsPDU.TP_UDL := EmptyStr;
_smsPDU.TP_UD := EmptyStr;
_smsPDU.PDUL := EmptyStr;
_smsPDU.PDU := EmptyStr;
if Copy(DstCode, 1, 2) <> '86' then
DstCode := '86' + DstCode;
_smsPDU.SCAL := IntToHex(sms_InvertNumbers(SMSC_YD, _smsPDU.SCA) div 2 + 1, 2); //联通
//_smsPDU.SCAL := IntToHex(sms_InvertNumbers(SMSC_YD, _smsPDU.SCA) + 1, 2); //移动
_smsPDU.SCAT := '91';
//_smsPDU.SCA := sms_Inver;
_smsPDU.TP_BR := '11';
_smsPDU.TP_MR := '00';
_smsPDU.TP_AL := IntToHex(sms_InvertNumbers(DstCode, _smsPDU.TP_AD) - 1, 2);
_smsPDU.TP_AT := '91';
_smsPDU.TP_PID := '00';
//_smsPDU.TP_DCS := IntToHex(DCS, 2); //去掉了DCS参数,使用固定值 2004-09-07
//_smsPDU.TP_VP := IntToHex(VP, 2); //去掉了VP参数,使用固定值
//_smsPDU.TP_DCS := IntToHex(DCS, 2); //DCS= 0是7位编码方式 4 是表示采用8位编码方式 8是Unicode方式
_smsPDU.TP_DCS := IntToHex(8,2);
_smsPDU.TP_VP := IntToHex(0, 2);
_smsPDU.TP_SCTS := '';
_smsPDU.TP_UDL := IntToHex(sms_AnsiToUnicode(UD, _smsPDU.TP_UD),2);
_smsPDU.PDU := _smsPDU.SCAL + _smsPDU.SCAT + _smsPDU.SCA + _smsPDU.TP_BR + _smsPDU.TP_MR
+ _smsPDU.TP_AL + _smsPDU.TP_AT + _smsPDU.TP_AD + _smsPDU.TP_PID + _smsPDU.TP_DCS
+ _smsPDU.TP_VP + _smsPDU.TP_SCTS + _smsPDU.TP_UDL + _smsPDU.TP_UD;//+#13; //#13为发送短信的回车符
_smsPDU.PDUL := IntToStr(Length(_smsPDU.PDU) div 2 - strToInt('$' + Copy(_smsPDU.PDU, 1, 2)) - 1); //最后-1-1的意思是:SCAL ///or and #13 的长度
end;
procedure TForm.SendData(Str: String);
begin
SPCommGSM.WriteCommData(PChar(Str), Length(Str));
Wait(100);
end;
发送时使用
SendData(smsSendPDU.PDU + #26);
接收时:
procedure TForm.SPCommGSMReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var str: string;
begin
SetLength(str, BufferLength);
Move(Buffer^, PChar(str)^, BufferLength);
//PurgeComm(TSPComm(Sender).Handle, PURGE_RXABORT or PURGE_RXCLEAR);
memo1.Lines.Add(str);
smscontent := smscontent + str;
end;