程序收发短信(100分)

  • 主题发起人 主题发起人 soonlearn
  • 开始时间 开始时间
S

soonlearn

Unregistered / Unconfirmed
GUEST, unregistred user!
我想做个小程序,能发送和接收短信,并对所回复的短信(可以规定回复的格式,比如数字)进行判断,可能使用GPRS/GSM Modem或者手机,请问有什么好的免费短信控件或程序例子吗?谢谢大家啦
 
GSM Modem一般会有说明书,收发短信主要是要能正确识别其短信编码,网上可以找到很多这种东西.
 
谢谢piaosiy,我怎么找半天都找不到,能贴个例子这里看吗?
 
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3233514
 
谢,我看看先[:D]
 
问题: 跪求通过GSM MODEM或者手机收发短信的程序资料 ( 积分: 100 )
分类: 局域网 / 通讯

来自: luozi, 时间: 2004-02-10 16:49:00, ID: 2445896
我要在几天内完成这个东西,现在连GSM MODEM都没见到,只是看了一些相关的AT指令文档。各位大侠能否提供相关的源代码或者资料,包括pdu格式的转换等等。有整套程序者另外发贴给1000分。

来自: luozi, 时间: 2004-02-10 19:12:00, ID: 2446020
不会没人有吧?

来自: luozi, 时间: 2004-02-10 19:13:00, ID: 2446023
有相关资料请发到我的邮箱:jp_luo@sina.com
谢谢。

来自: mmyl, 时间: 2004-02-10 19:17:00, ID: 2446030
如果哪位大虾有,请给我一份,给高分,在这里先谢过!
Email:myl_myl@163.com

来自: sxzqcyj, 时间: 2004-02-10 20:05:00, ID: 2446097
目前手机短信息的应用越来越广泛,互联网上提供短信息发送的站点也越来越多,但一些站点的服务并不尽如人意,往往发出去的短信息石沉大海。最可靠的发送方法当然是用手中的手机了,如果设置了状态报告,更能确切知道对方是否收到了此条信息。手机发送尽管比较可靠, 但也存在输入麻烦、效率低的问题。本文介绍一种方法,只要手机能够与电脑相连(通过红外端口或用手机数据线连接串行口,同时手机支持GSM AT指令集),就可以通过自行编制的短信息发送软件,实现短信息的发送。 现在市场上的大多数手机均支持类似于Modem控制的GSM AT指令集,该指令集是由诺基亚、爱立信、摩托罗拉和HP等厂家共同为GSM系统研制的,其中包含了对SMS(Short Message Service)的控制。 GSM AT相关指令的介绍 与SMS有关的GSM AT指令如表1所示: 表1 相关的GSM AT指令对SMS的控制共有三种实现途径: Block Mode; 基于AT命令的Text Mode; 基于AT命令的PDU Mode。 Text Mode比较简单,多款诺基亚手机均支持该模式。西门子的手机大多只支持PDU模式,PDU模式是发送或接收手机SMS信息的一种方法,短信息正文经过十六进制编码后被传送。目前,PDU已取代Block Mode,因此本文主要探讨PDU模式的发送。 计算机和手机的通信 本文以西门子 S3568i为例,介绍如何实现短信息的发送。 数据线连接 首先,通过S35/25数据线将手机与电脑串行口相连。然后,打开超级终端,选择直接串行口连接,端口参数设为19200速率、无校验、数据位8、停止位1。 红外线连接 如果使用带红外端口的计算机,可以设置与手机的无线连接。首先确认计算机红外端口已打开,并将手机的红外线和收传真/数据功能打开,对接红外端口,计算机系统托盘上应当出现一个红外设备西门子S35(如果没有安装红外监视器,则不显示)。然后,打开超级终端,选择IrDa上的串行口。 连接测试 点击超级终端工具条上的呼叫按钮,输入AT并回车,屏幕上如果出现OK则表明计算机与手机的连接成功,这时就可以输入各类GSM AT指令了。 如:查询手机厂家,输入AT+CGMI=<CR>,屏幕显示Siemens。 通常情况下,执行测试命令AT+CMGS=?<CR>,如果返回OK,表明手机支持此指令。该指令的完整语法格式如下: If PDU mode (+CMGF=0)+CMGS=<length><CR>PDU is given <ctrl-Z/ESC> 如果短信息格式指令AT+CMGF返回的是0,则SMS格式为PDU模式,再执行AT+CMGS=<数据长度>命令后,手机返回“>”符号并等待输入,输入PDU数据并以^Z或Esc键结束。 如果信息发送成功,则返回OK,并显示信息号: +CMGS: <mr> 如果发送失败,则返回如下信息: +CMS ERROR: <err> PDU数据格式的分析 下面通过对存储在手机中的待发信息的分析,来介绍SMS PDU的数据格式。首先,用手机写一条短信息,发送手机号码为13605696031,信息内容为“Hello World!”。通过执行AT+CMGL=2可以读出此条信息。 操作过程如下(斜体字符为响应信息,{}内为注释): AT OK AT+CMGL=2 {读未发短信息} +CMGL: 1,2,,24 {1表示信息个数,2表示未发信息,24表示信息总容量} 08 91 683108501505F0 11 00 0B 81 3106656930F1 0000A7 0B E8329BFD06DDDF723619 OK  下面分析这条信息: 08:短信息中心地址长度。 91:短信息中心号码类型,91是TON/NPI。TON/NPI遵守International/E.164标准,指在号码前需加‘+’号;此外还可有其他数值,但91最常用。 683108501505F0:短信息号码,是所使用的服务中心地址。由于位置上略有处理,实际号码应为:8613805515500(字母F意指长度减1),这是作者所在地GSM短信息中心的号码。 11:文件头字节(header byte,是一种bitmask)。这里11指正常地发送短信息。 00:信息类型。 0B:被叫号码长度。 81:被叫号码类型。 3106656930F1:被叫号码,也经过了移位处理,实际号码为13605696031。 0000A7:短信息编码类型GSM Default Alphabet,如为中文则是000010。 0B:短信息长度。 E8329BFD06DDDF723619:短信息内容“Hello World!”。 短信息的编码方法及编程实现 下面我们介绍纯英文和纯中文的信息编码方法。通过测试我们发现,每条发送的短信息前面部分均相同,只是被叫号码和短信息内容有变化。 1.英文编码 参见表2,设短信息内容为“Hello World!”。缺省的GSM 字符集为7位编码,可以简单地理解为ASCII码(ASCII值小于80Hex,因此,Bit8被忽略),依次将下一7位编码的后几位逐次移至前面,形成新的8位编码,参见表2箭头指示。需要注意的是第9行,移位计数已达7位,则直接将本编码前加0。GSM并非支持所有的ASCII字符显示。 表2 英文编码的实现过程 下面是实现英文编码的部分Delphi 5代码: //英文格式编码,s为String function Encode1(var s:String):String; var i,j,len:Integer; cur:Integer; t:String; begin Result:=‘’; len:=Length(s); //j 用于移位计数 i:=1;j:=0; while i<=len do begin if i<len then //数据变换 cur:=(ord(s) shr j) or ((ord(s[i+1]) shl (7-j)) and $ff) else cur:=(ord(s) shr j) and $7f; FmtStr(t,‘%2.2X’,[cur]); Result:=Result+t; inc(i); //移位计数达到7位的特别处理 j:=(j+1) mod 7;if j=0 then inc(i); end; end;   2.中文编码 参见表3,设短信息内容为“中文短信息”。中文短信息的实现较简单,只需将GB2312的中文编码转换为代码页为CP936的Unicode编码即可。 表3 中文编码的实现过程 通过Delphi的WideString类型转换,可以巧妙地实现GB2312到Unicode的编码转换(注意代码页和操作系统相关联)。下面是实现中文编码的部分Delphi 5代码: // 中文格式编码,s为Unicode String function Encode2(var s:WideString):String; var i,len:Integer; cur:Integer; t:String; begin Result:=‘’; len:=Length(s); i:=1; while i<=len do begin cur:=ord(s); //BCD转换 FmtStr(t,‘%4.4X’,[cur]); Result:=Result+t; inc(i); end; end; 小 结 以上介绍了PDU格式的短信息编码。建议英文信息长度不超过140个字符,中文信息不要超过54个汉字。如果使用能够支持文本方式的手机进行发送,实现起来更简单。如发送“Hello World!”,用如下的AT指令即可: AT+CGMF=1<CR>AT+CGMS=“13605696031”,129<CR> >Hello World!<^Z>



来自: luozi, 时间: 2004-02-11 16:50:23, ID: 2447864
还有没有啊?中英文混合在一起的时候怎么生成PDU码??

来自: 不可一世, 时间: 2004-02-11 16:54:19, ID: 2447873
要做短信网关

来自: pcplayer, 时间: 2004-02-12 12:02:02, ID: 2449380
PDU码有一套算法规则的。最要命的是,不同厂家的手机,其PDU码遵循的规则不完全相同。

如果你已经确定了用某种型号的手机,问题才好办。看你的样子是使用工业手机模块?工业模块的AT命令集比较简单,也比较符合标准的命令集,很少自己加的东东。

我以前写过一些这样的程序。



来自: luozi, 时间: 2004-02-12 20:18:26, ID: 2450479
唉,自己摸了几天,总算搞清楚了。
谢谢大家的关注。


来自: gdtkd, 时间: 2004-02-23 10:06:36, ID: 2467330
很简单吗!网上有很多资料!

来自: yostgxf, 时间: 2004-02-23 14:57:52, ID: 2467671
手机短信息SMS的Delphi源代码 (转载)
目前手机短信息的应用越来越广泛,互联网上提供短信息发送的站点也越来越多,但一些站点的服务并不尽如人意,往往发出去的短信息石沉大海。最可靠的发送方法当然是用手中的手机了,如果设置了状态报告,更能确切知道对方是否收到了此条信息。手机发送尽管比较可靠, 但也存在输入麻烦、效率低的问题。本文介绍一种方法,只要手机能够与电脑相连(通过红外端口或用手机数据线连接串行口,同时手机支持GSM AT指令集),就可以通过自行编制的短信息发送软件,实现短信息的发送。
现在市场上的大多数手机均支持类似于Modem控制的GSM AT指令集,该指令集是由诺基亚、爱立信、摩托罗拉和HP等厂家共同为GSM系统研制的,其中包含了对SMS(Short Message Service)的控制。
GSM AT相关指令的介绍
与SMS有关的GSM AT指令如表1所示:

表1 相关的GSM AT指令
对SMS的控制共有三种实现途径:
Block Mode;
基于AT命令的Text Mode;
基于AT命令的PDU Mode。
Text Mode比较简单,多款诺基亚手机均支持该模式。西门子的手机大多只支持PDU模式,PDU模式是发送或接收手机SMS信息的一种方法,短信息正文经过十六进制编码后被传送。目前,PDU已取代Block Mode,因此本文主要探讨PDU模式的发送。
计算机和手机的通信
本文以西门子 S3568i为例,介绍如何实现短信息的发送。
数据线连接
首先,通过S35/25数据线将手机与电脑串行口相连。然后,打开超级终端,选择直接串行口连接,端口参数设为19200速率、无校验、数据位8、停止位1。
红外线连接
如果使用带红外端口的计算机,可以设置与手机的无线连接。首先确认计算机红外端口已打开,并将手机的红外线和收传真/数据功能打开,对接红外端口,计算机系统托盘上应当出现一个红外设备西门子S35(如果没有安装红外监视器,则不显示)。然后,打开超级终端,选择IrDa上的串行口。
连接测试
点击超级终端工具条上的呼叫按钮,输入AT并回车,屏幕上如果出现OK则表明计算机与手机的连接成功,这时就可以输入各类GSM AT指令了。
如:查询手机厂家,输入AT+CGMI=,屏幕显示Siemens。
通常情况下,执行测试命令AT+CMGS=?,如果返回OK,表明手机支持此指令。该指令的完整语法格式如下:
If PDU mode (+CMGF=0)+CMGS=PDU is given
如果短信息格式指令AT+CMGF返回的是0,则SMS格式为PDU模式,再执行AT+CMGS=<数据长度>命令后,手机返回“>”符号并等待输入,输入PDU数据并以^Z或Esc键结束。
如果信息发送成功,则返回OK,并显示信息号:
+CMGS:
如果发送失败,则返回如下信息:
+CMS ERROR:
PDU数据格式的分析
下面通过对存储在手机中的待发信息的分析,来介绍SMS PDU的数据格式。首先,用手机写一条短信息,发送手机号码为13605696031,信息内容为“Hello World!”。通过执行AT+CMGL=2可以读出此条信息。
操作过程如下(斜体字符为响应信息,{}内为注释):
AT
OK
AT+CMGL=2 {读未发短信息}
+CMGL: 1,2,,24 {1表示信息个数,2表示未发信息,24表示信息总容量}
08 91 683108501505F0 11 00 0B 81 3106656930F1 0000A7 0B E8329BFD06DDDF723619
OK 
下面分析这条信息:
08:短信息中心地址长度。
91:短信息中心号码类型,91是TON/NPI。TON/NPI遵守International/E.164标准,指在号码前需加‘+’号;此外还可有其他数值,但91最常用。
683108501505F0:短信息号码,是所使用的服务中心地址。由于位置上略有处理,实际号码应为:8613805515500(字母F意指长度减1),这是作者所在地GSM短信息中心的号码。
11:文件头字节(header byte,是一种bitmask)。这里11指正常地发送短信息。
00:信息类型。
0B:被叫号码长度。
81:被叫号码类型。
3106656930F1:被叫号码,也经过了移位处理,实际号码为13605696031。
0000A7:短信息编码类型GSM Default Alphabet,如为中文则是000010。
0B:短信息长度。
E8329BFD06DDDF723619:短信息内容“Hello World!”。
短信息的编码方法及编程实现
下面我们介绍纯英文和纯中文的信息编码方法。通过测试我们发现,每条发送的短信息前面部分均相同,只是被叫号码和短信息内容有变化。
1.英文编码
参见表2,设短信息内容为“Hello World!”。缺省的GSM 字符集为7位编码,可以简单地理解为ASCII码(ASCII值小于80Hex,因此,Bit8被忽略),依次将下一7位编码的后几位逐次移至前面,形成新的8位编码,参见表2箭头指示。需要注意的是第9行,移位计数已达7位,则直接将本编码前加0。GSM并非支持所有的ASCII字符显示。
表2 英文编码的实现过程

下面是实现英文编码的部分Delphi 5代码:
//英文格式编码,s为String
function Encode1(var s:String):String;
var
i,j,len:Integer;
cur:Integer;
t:String;
begin
Result:=‘’;
len:=Length(s);
//j 用于移位计数
i:=1;j:=0;
while i<=len do
begin
if i//数据变换
cur:=(ord(s) shr j) or ((ord(s[i+1]) shl (7-j)) and $ff)
else
cur:=(ord(s) shr j) and $7f;
FmtStr(t,‘%2.2X’,[cur]);
Result:=Result+t;
inc(i);
//移位计数达到7位的特别处理
j:=(j+1) mod 7;if j=0 then inc(i);
end;
end;  
2.中文编码
参见表3,设短信息内容为“中文短信息”。中文短信息的实现较简单,只需将GB2312的中文编码转换为代码页为CP936的Unicode编码即可。
表3 中文编码的实现过程

通过Delphi的WideString类型转换,可以巧妙地实现GB2312到Unicode的编码转换(注意代码页和操作系统相关联)。下面是实现中文编码的部分Delphi 5代码:
// 中文格式编码,s为Unicode String
function Encode2(var s:WideString):String;
var
i,len:Integer;
cur:Integer;
t:String;
begin
Result:=‘’;
len:=Length(s);
i:=1;
while i<=len do
begin
cur:=ord(s);
//BCD转换
FmtStr(t,‘%4.4X’,[cur]);
Result:=Result+t;
inc(i);
end;
end;
小 结
以上介绍了PDU格式的短信息编码。建议英文信息长度不超过140个字符,中文信息不要超过54个汉字。如果使用能够支持文本方式的手机进行发送,实现起来更简单。如发送“Hello World!”,用如下的AT指令即可:
AT+CGMF=1AT+CGMS=“13650246680”,129
>Hello World!<^Z>

来自: luozi, 时间: 2004-02-28 17:34:23, ID: 2475874
发分.

得分大富翁: gdtkd-20,pcplayer-20,sxzqcyj-30,yostgxf-20,不可一世-10,
 
问题: 关于手机GSM MODEM的收发短信问题! ( 积分: 50 )
分类: 局域网 / 通讯

来自: lzplzp001, 时间: 2004-04-24 9:50:00, ID: 2578107
我用WAVECOM的GSM MODEM做了一个收发短信的程序!但是遇到了两个问题!请高手指点
1、收到到的短信怎么解码,一般的中文的可以解码!但是纯英文的却无法解码(PDU码)!
2、群发短信的时候,设断点测试可以循环群发短信,但是程序直接运行却无法群发!!
我已经设置了SLEEP(4000)了!




来自: lzplzp001, 时间: 2004-04-24 11:04:39, ID: 2578233
没有人知道吗?

来自: gyh75, 时间: 2004-04-24 14:42:51, ID: 2578531
1.纯英文解码(PDU码)
function DecodeE(s: string): string;
function HexCharToInt(HexToken: char): Integer;
begin
{if HexToken>#97 then HexToken:=Chr(Ord(HexToken)-32);
{ use lowercase aswell }

Result := 0;

if (HexToken > #47) and (HexToken < #58) then { chars 0....9 }
Result := Ord(HexToken) - 48
else
if (HexToken > #64) and (HexToken < #71) then { chars A....F }
Result := Ord(HexToken) - 65 + 10;
end;

function HexCharToBin(HexToken: char): string;
var
DivLeft: integer;
begin
DivLeft := HexCharToInt(HexToken); { first HEX->BIN }
Result := '';
{ Use reverse dividing }
repeat { Trick; divide by 2 }
if odd(DivLeft) then { result = odd ? then bit = 1 }
Result := '1' + Result { result = even ? then bit = 0 }
else
Result := '0' + Result;

DivLeft := DivLeft div 2; { keep dividing till 0 left and length = 4 }
until (DivLeft = 0) and (length(Result) = 4); { 1 token = nibble = 4 bits }
end;

function HexToBin(HexNr: string): string;
{ only stringsize is limit of binnr }
var
Counter: integer;
begin
Result := '';

for Counter := 1 to length(HexNr) do
Result := Result + HexCharToBin(HexNr[Counter]);
end;

function pow(base, power: integer): integer;
var
counter: integer;
begin
Result := 1;

for counter := 1 to power do
Result := Result * base;
end;

function BinStrToInt(BinStr: string): integer;
var
counter: integer;
begin
if length(BinStr) > 16 then
raise ERangeError.Create(#13 + BinStr + #13 +
'is not within the valid range of a 16 bit binary.' + #13);

Result := 0;

for counter := 1 to length(BinStr) do
if BinStr[Counter] = '1' then
Result := Result + pow(2, length(BinStr) - counter);
end;

var
OctetStr: string;
OctetBin: string;
Charbin: string;
PrevOctet: string;
Counter: integer;
Counter2: integer;
begin
PrevOctet := '';
Result := '';

for Counter := 1 to length(s) do
begin
if length(PrevOctet) >= 7 then { if 7 Bit overflow on previous }
begin
if BinStrToInt(PrevOctet) <> 0 then
Result := Result + Chr(BinStrToInt(PrevOctet))
else
Result := Result + ' ';

PrevOctet := '';
end;

if Odd(Counter) then { only take two nibbles at a time }
begin
OctetStr := Copy(s, Counter, 2);
OctetBin := HexToBin(OctetStr);

Charbin := '';
for Counter2 := 1 to length(PrevOctet) do
Charbin := Charbin + PrevOctet[Counter2];

for Counter2 := 1 to 7 - length(PrevOctet) do
Charbin := OctetBin[8 - Counter2 + 1] + Charbin;

if BinStrToInt(Charbin) <> 0 then
Result := Result + Chr(BinStrToInt(CharBin))
else
Result := Result + ' ';

PrevOctet := Copy(OctetBin, 1, length(PrevOctet) + 1);
end;
end;
end;

2.在AT+CMGS= ....后Sleep(3000); 然后写入信息发送后,再Sleep(4000)
然后循环


来自: lzplzp001, 时间: 2004-04-24 19:10:43, ID: 2578880
感谢你的支持!
第一、用PDU格式(at+cmgf=0)接收短信时无法分辨是否是纯英文,我就算有英文的解码和中文的解码程序!但是也无法确定对方发给我的是何种类的短信!
第二、发送时代码是这样的!代码用的是SPCOMM控件的。单步执行没有问题!但是不设断点运行会出错。
mess:='at+cmgf=0'+#13;
comm1.WriteCommData(pchar(mess),Length(mess));
Sleep(2000);
mess:='at+cmgs='+发送短信长度+#13+短信的PDU编码+#26+#13;
comm1.WriteCommData(pchar(mess),Length(mess));
Sleep(4000);
出错的信息:

at+cmgf=0

OK

at+cmgs=138
0011
> 000B813108729201F20008107C002A4E0A6D77516B767E4F34004A0034003400360035002A4E0A6D77516B767E4F3400500036003900340037002A4E0A6D774E1C65B9004A0035003300320032002A4E0A6D774E1C65B900500033003900350036002A4E0A6D778679686500500033003000340030002A4E0A6D77534E805400500035003300390035

at+cmgs=138
00
ERROR
F033753130
+CMGS: 217


来自: lzplzp001, 时间: 2004-04-24 19:15:47, ID: 2578884
试过,第二个问题已经解决!
第一个问题请教有没有什么好方法!!可以加分!!

来自: lzplzp001, 时间: 2004-04-24 19:26:26, ID: 2578900
第一个问题也就是如何确定对方发送的是纯英文还是中英混编!!
如果是纯英文,可以用你的解码程序解码,如果不是,则需要用中文解码程序解码!
你做过吗?如何解决的??有代码最好!

来自: gyh75, 时间: 2004-04-24 19:51:44, ID: 2578917
如:
0891683108301105F0000D91683137882787F2 00 [red]08[/red] 40307241112300 04 4E2D56FD
先判断接收数据的红色部分 :08为中文编码,00为英文编码

来自: lzplzp001, 时间: 2004-04-26 10:17:08, ID: 2580658
谢谢!!有效!

得分大富翁: gyh75
 
手机收发短信仅仅就是使用几个at命令,很简单.
不过短信的PDU编码编码有点麻烦,看看我的,编码和解码完全版,拿过来就可以用.
http://www.delphibbs.com/keylife/iblog_show.asp?xid=22411
第二,可以使用一个开源的手机管理动态库.gammu-1.07.00,多平台版本.
除了可以处理短信外,还可以管理手机,比如电话簿,呼叫等,代码特别完善,最新更新是在2006-06-11.
 
AT指令拉
 
我做过类似的程序,我的接受做完了,接受有了容量限制的问题,正常的卡只能存20或者30条记录,我用线程做的处理,卡做为了缓存,多少数据都别存到库里了,卡里的数据被清空了,发的部分我认为很好做了,我是在以前公司做的,也许我做的很麻烦,各位有什么高招么 。另外我想问个问题,我要是不把原代码给原来公司是不是可以,那个部长为了要原代码,压着我工资,我把代码给他,才把工资给我,你们是怎么保护自己的代码的。
 
多人接受答案了。
 

Similar threads

D
回复
0
查看
867
DelphiTeacher的专栏
D
D
回复
0
查看
836
DelphiTeacher的专栏
D
D
回复
0
查看
753
DelphiTeacher的专栏
D
后退
顶部