用GSM模块发中文短讯,必须以PDU包的形式发送。我将它写成了Dll,直接调用SMSEncode函数即可得到追后的编码。现将原码公开: unit EnCodeCompnent;interfaceuses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; function SMSEncode(s:WideString;Result_Code:pchar):Bool;Stdcall;export; function SMSDecode(Input_Code:pchar;Result_Str:pchar):Bool;Stdcall;export; function MakePDU(DestNumber:pchar;Content:pchar;Result_String:pchar):Bool;stdcall;export; function ConvertPhoneNum(strNum:string):string; function Transposition(instr:pchar;Result_str:pchar):Bool;stdcall;export;//将一个字符串两两交换位置 { Public declarations }implementation function SMSEncode(s:WideString;Result_Code:pchar):Bool; var i,len:Integer; cur:Integer; t,temp:String; begin if length(s)>0 then begin len:=Length(s); i:=1; while i<=len do begin cur:=ord(s[i]); //BCD convert FmtStr(t,'%4.4X',[cur]); temp:=temp+t; inc(i); end; StrCopy(Result_Code,pchar(temp)); Result:=true; end else Result:=false; end;function SMSDecode(Input_Code:pchar;Result_Str:pchar):Bool; var str:string; i:integer; temp:string; A_PWideChar:array[0..300] of widechar; R_String:string; A_integer:integer; begin str:=string(Input_Code); R_String:=''; if length(str)<=0 then begin Result:=false; exit; end; i:=0; while i<length(str) do begin temp:=copy(str,i+1,4); A_integer:=strtoint('$'+temp); move(A_integer,A_PWideChar[i div 4],sizeof(A_PWideChar[i div 4])); inc(i,4); end; A_PWideChar[length(str) div 4]:=#0; R_String:=WideCharToString(@A_PWideChar); StrCopy(Result_Str,pchar(R_String)); Result:=true; end; function MakePDU(DestNumber:pchar;Content:pchar;Result_String:pchar):Bool; const lenSmsInfo='00'; firstOctet='11'; TPMessageReference='00'; TypeOfAddress='91'; TpId='00'; TpDcs='08';//"00" is 7 bit encode "08" is 8 bit encode; TPValidityPeriod='AA';//aa is 4 day var DestPhoneNum:string; AddressLength:string; TpUserData:string; TPUserDataLength:string; temp:WideString; Tmp_Pchar:pchar; Rlt_str:string; begin if (DestNumber='') or (Content='') then begin Result:=false; exit; end else begin DestPhoneNum:=ConvertPhoneNum(DestNumber); AddressLength:=format('%2.2X',[length(DestNumber)]); temp:=Content; Tmp_Pchar:=StrAlloc(1000); if SMSEncode(temp,Tmp_Pchar) then TpUserData:=string(Tmp_Pchar); if TpDcs='08' then TPUserDataLength:=format('%2.2X',[length(TpUserData) div 2]) else TPUserDataLength:=format('%2.2X',[((length(TpUserData) div 2)*8) div 7]); Rlt_str:=lenSmsInfo +firstOctet +TPMessageReference +AddressLength +TypeOfAddress +DestPhoneNum +TpId +TpDcs +TPValidityPeriod +TPUserDataLength +TpUserData;//TpUserData have to Encoded; StrCopy(Result_String,pchar(Rlt_str)); Result:=true; end; end;function ConvertPhoneNum(strNum:string):string; var i:integer; str:string; A_Pchar:pchar; begin str:=strNum; i:=length(str); if odd(i) then begin str:=str+'F'; A_Pchar:=StrAlloc(40); if Transposition(pchar(str),A_pchar) then result:=string(A_Pchar) else result:='Null'; end else begin A_Pchar:=StrAlloc(40); if Transposition(pchar(str),A_pchar) then result:=string(A_Pchar) else result:='Null'; end; end;function Transposition(instr:pchar;Result_str:pchar):Bool; var i:integer; temp:string; destStr:string; In_String:string; begin if length(instr)>0 then begin destStr:=''; In_String:=string(instr); setlength(In_String,length(In_String)); i:=1; while i<length(In_String) do begin temp:=In_String[i+1]+In_String[i]; destStr:=destStr+temp; inc(i,2); end; StrCopy(Result_Str,pchar(destStr)); result:=true; end else begin result:=false; end; end;
gordon9673 :用PC通过手机发送短信?我是用手机数据线来发送的,例如用我的PC连好了NOKIA6110的数据线,通过COM1来连接,我察过资料,我的想法是,先用CREATEFILE创建连接,然后用WRITEFILE来传送我的消息,nokia的手机大部分都支持TEXT的格式,是吧,例如,我在EDIT中输入:‘AT ?’,然后用WRITEFILE向COM1发送数据,这样可以吗?如果可以,拿我怎么接收它的返回信息呢?(显示在MEON1)上。deathcat:发送短消息有很多种方法.第一:控制手机,第二:控制GSM模块,第三:通过短消息网关。在GSM协议中.有MT,ME,不知道你说的究竟是什么,说清楚点。
1.去查阅AT命令集+GSM0707协议+GSM0705协议.
2.从手机制造商哪里下载软件.
根据AT命令集.没有"AT?"这个命令.(但是不知道NOKIA有没有).标准的text文本发送模式:
发送:
at+cmgs="+86(手机号码)"+#13+#10
返回:
>发送:
消息内容返回:
+CMGS [发送标号]
OK至于接收.你用的应该是Comm控件吧,当ReceiveCount>0的时候,缓冲区有数据,用Input的方法就可以读出来了. gordon9673 :谢谢。我还想知道用PDU格式发送时,必须把AT命令转化成16进制的数吗?该怎么转换?gordon9673 (gody) :
这个好象可以啊
http://www.yiwant.com/download1.htm
电脑连接手机收发短消息的二次开发工具,包括一个实现短消息收发功能的DLL、函数说明和一个DELPH程序源代码。
www.yiwant.com/cgi-bin/click.cgi?job=down&filename=sms-delphi
部分程序:
mplementation{$R *.DFM}
//=============DLL 函数调用声明 开始 =========
procedure ConnectToMobile;stdcall; external 'SMSLIB.DLL';
procedure DisconnectToMobile;stdcall; external 'SMSLIB.DLL';
Function IsConnected:boolean;stdcall; external 'SMSLIB.DLL';
Function IsBusy:boolean;stdcall; external 'SMSLIB.DLL';
procedure InitMobile;stdcall; external 'SMSLIB.DLL';
procedure SetSMC(SMC:PChar);stdcall; external 'SMSLIB.DLL';
Function SendSMS(phone,text:PChar):boolean;stdcall; external 'SMSLIB.DLL';
Function ReadSMS(Text,sendnum,smc,time:PChar):boolean;stdcall; external 'SMSLIB.DLL';
//=============DLL 函数调用声明 结束 =========procedure TForm1.Button1Click(Sender: TObject);
begin
ConnectToMobile;
memo2.Lines.Add ('已经发出连接命令。');
sleep(4000); //等待4秒,等待手机准备好
while not IsConnected do ; //直到连接成功 memo2.Lines.Add ('已经连接到手机。');
InitMobile;
memo2.Lines.Add ('已经初始化。');
SetSMC(PChar(SMC.Text ));
memo2.Lines.Add ('短信中心设置成功。');end; deathcat:
使用pdu格式可以啊。
at+cmgf=0 ----使用pdu模式
at+cmgf=1 ----使用text模式
但是,你首先要看nokia的手机是否支持pdu格式。
不过,我想应该是支持的。
因为text模式不支持中文短消息。你要先查查pdu格式手册,每一个短信中心的pdu格式不是很一致的。
没有必要做什么16进制的转换啊。如果发送中文,那么用的是uc2码。比如说发送给手机号码为123456789ab的手机发送1234。那么pdu格式应该是
0891683108200905f011000b816821436587a9fb0004+短信息内容长度(16进制)+短信息内容
unit EnCodeCompnent;interfaceuses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; function SMSEncode(s:WideString;Result_Code:pchar):Bool;Stdcall;export;
function SMSDecode(Input_Code:pchar;Result_Str:pchar):Bool;Stdcall;export;
function MakePDU(DestNumber:pchar;Content:pchar;Result_String:pchar):Bool;stdcall;export;
function ConvertPhoneNum(strNum:string):string;
function Transposition(instr:pchar;Result_str:pchar):Bool;stdcall;export;//将一个字符串两两交换位置
{ Public declarations }implementation
function SMSEncode(s:WideString;Result_Code:pchar):Bool;
var
i,len:Integer;
cur:Integer;
t,temp:String;
begin
if length(s)>0 then
begin
len:=Length(s);
i:=1;
while i<=len do
begin
cur:=ord(s[i]);
//BCD convert
FmtStr(t,'%4.4X',[cur]);
temp:=temp+t;
inc(i);
end;
StrCopy(Result_Code,pchar(temp));
Result:=true;
end
else
Result:=false;
end;function SMSDecode(Input_Code:pchar;Result_Str:pchar):Bool;
var
str:string;
i:integer;
temp:string;
A_PWideChar:array[0..300] of widechar;
R_String:string;
A_integer:integer;
begin
str:=string(Input_Code);
R_String:='';
if length(str)<=0 then
begin
Result:=false;
exit;
end;
i:=0;
while i<length(str) do
begin
temp:=copy(str,i+1,4);
A_integer:=strtoint('$'+temp);
move(A_integer,A_PWideChar[i div 4],sizeof(A_PWideChar[i div 4]));
inc(i,4);
end;
A_PWideChar[length(str) div 4]:=#0;
R_String:=WideCharToString(@A_PWideChar);
StrCopy(Result_Str,pchar(R_String));
Result:=true;
end;
function MakePDU(DestNumber:pchar;Content:pchar;Result_String:pchar):Bool;
const
lenSmsInfo='00';
firstOctet='11';
TPMessageReference='00';
TypeOfAddress='91';
TpId='00';
TpDcs='08';//"00" is 7 bit encode "08" is 8 bit encode;
TPValidityPeriod='AA';//aa is 4 day
var
DestPhoneNum:string;
AddressLength:string;
TpUserData:string;
TPUserDataLength:string;
temp:WideString;
Tmp_Pchar:pchar;
Rlt_str:string;
begin
if (DestNumber='') or (Content='') then
begin
Result:=false;
exit;
end
else
begin
DestPhoneNum:=ConvertPhoneNum(DestNumber);
AddressLength:=format('%2.2X',[length(DestNumber)]);
temp:=Content;
Tmp_Pchar:=StrAlloc(1000);
if SMSEncode(temp,Tmp_Pchar) then
TpUserData:=string(Tmp_Pchar);
if TpDcs='08' then
TPUserDataLength:=format('%2.2X',[length(TpUserData) div 2])
else
TPUserDataLength:=format('%2.2X',[((length(TpUserData) div 2)*8) div 7]);
Rlt_str:=lenSmsInfo
+firstOctet
+TPMessageReference
+AddressLength
+TypeOfAddress
+DestPhoneNum
+TpId
+TpDcs
+TPValidityPeriod
+TPUserDataLength
+TpUserData;//TpUserData have to Encoded;
StrCopy(Result_String,pchar(Rlt_str));
Result:=true;
end;
end;function ConvertPhoneNum(strNum:string):string;
var
i:integer;
str:string;
A_Pchar:pchar;
begin
str:=strNum;
i:=length(str);
if odd(i) then
begin
str:=str+'F';
A_Pchar:=StrAlloc(40);
if Transposition(pchar(str),A_pchar) then
result:=string(A_Pchar)
else
result:='Null';
end
else
begin
A_Pchar:=StrAlloc(40);
if Transposition(pchar(str),A_pchar) then
result:=string(A_Pchar)
else
result:='Null';
end;
end;function Transposition(instr:pchar;Result_str:pchar):Bool;
var
i:integer;
temp:string;
destStr:string;
In_String:string;
begin
if length(instr)>0 then
begin
destStr:='';
In_String:=string(instr);
setlength(In_String,length(In_String));
i:=1;
while i<length(In_String) do
begin
temp:=In_String[i+1]+In_String[i];
destStr:=destStr+temp;
inc(i,2);
end;
StrCopy(Result_Str,pchar(destStr));
result:=true;
end
else
begin
result:=false;
end;
end;
1. 找网上的免费发短信的网站,用Http控件自己写表单提交,
不过现在很难能找到免费发短信的网站了。
2. 跟移动/联通联系,他们提供短信网关的接口,你写程序
连到他们的网关收发短信。前提是要申请到发短信的执照。
3. 通过你的手机发送,市场上有能通过手机发短信的设备,
用它提供的API写程序。
价格在1500左右!!