关于发送手机短讯的程序,请指教 (50分)

  • 主题发起人 主题发起人 disremember
  • 开始时间 开始时间
D

disremember

Unregistered / Unconfirmed
GUEST, unregistred user!
我想用delphi6写一个发手机短讯的程序,但不知从何入手,需要哪些关键技术呢?
有人能给个思路么?越详细越好
 
转载的,刚才好像刚有人问过,你也可以去参考那个帖子

目前手机短信息的应用越来越广泛,互联网上提供短信息发送的站点也越来越多,但一些站点的服务并不尽如人意,往往发出去的短信息石沉大海。最可靠的发送方法当然是用手中的手机了,如果设置了状态报告,更能确切知道对方是否收到了此条信息。手机发送尽管比较可靠, 但也存在输入麻烦、效率低的问题。本文介绍一种方法,只要手机能够与电脑相连(通过红外端口或用手机数据线连接串行口,同时手机支持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>
 
谢谢您的转贴,但我想要的是网络发短讯,而不是通过手机连接的
 
在delphi中文技巧集里也有几个.我再给你贴一个看看对你有没有用.

很多人一定用过OICQ,想必也用过了它的BP机短讯、手机短讯,编程的朋友一定想实现
这种功能,
如果你的程序能发到手机、发到BP机一定很酷。
现在我就介绍一种可行的方法。
一、原理
它不同于OICQ的双方都在网上才能进行交流的寻呼功能,它可以将文字
信息发送到真正的寻呼机上。只要你能够上网,就可以自己动手,随时随地将信息发送出去,即使你在国外,也可以利用它来向国内的友人发送信息了,而且不用交纳国际长途费用,
是不是方便又省事呢!
二、分析
现在网上各寻呼台都有网上服务网页寻呼(Web Paging)就是常用的一种。
它是通过在互联网上访问寻呼台的主页,然后由寻呼台的信息寻呼系统打传呼。所以我们
只要利用HTTP协议就可以实现网络寻呼了。以下就简单介绍一下HTTP协议:
HTTP中完成一个会话通常要完成:1)客户端程序与服务器建立连接2)发送请求3)服务器
响应客户端4)关闭连接
HTTP常用到的请求有:1)GET(请求一万维网页) 2)HEAD(读取一万维网页的头部)
3)PUT(请求一存储万维网页) 4)POST(附加一个命名的资源) 5)DELETE(删除万维网页)
6)LINK(连接两个已有的资源) 7)UNLINK(断开两个已有资源的连接)
HTTP中常用到的应答状态代码有:(*号代表0-9间的一个数) 1. 1** (信息)
2. 2**(成功) 3.4**(客户端错误) 4.5**(服务器错误)
其实我们要实现的程序,只用POST、GET请求,收到正常应答就可以了。POST可以用于
把用户输入的数据以数据流的方式传给CGI程序,CGI通过Contect-Length环境变量来取相应
长度的数据流信息。
POST请求格式如下:
POST http://www2.scuta.edu.cn/stu/chatroom/check.asp HTTP/1.0
Accept: image/gif image/x-xbitmap image/jpeg image/pjpeg application/vnd.ms-powerpoint application/vnd.ms-excel application/msword */*
Referer: http://www2.scuta.edu.cn/stu/
Accept-Language: zh-cn
Content-Type: application/x-www-form-urlencoded
Proxy-Connection: Keep-Alive
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)
Host: www2.scuta.edu.cn
Content-Length: 87
Pragma: no-cache
Cookie: ASPSESSIONIDQGGGQHHE=ABGNNOJCIGOFCDLBIOLHKAFK
服务器正常应答的头部结构为:
200 OK HTTP/1.0 说明提交数据成功
三、程序的实现
Delphi中NMHTTP已经可以很容易的实现上面的所说的数据提交而且它还支
持Proxy、这样对于通过代理服务器上网一样可以适用,并且它不是OICQ中发送讯信所用
到SOCKET5代理。
新建一个窗体,加入组件一个ComboBox,命名为callto 用于存放寻呼对象,如国信寻
呼就有95908、94908、94909、98062、98063、98019、98035、98052、98038、99055、
98060、98061、98051、98003、99062、99016、99017、99018、99019、99046、99076;
加入组件Edit,命名为tonumber,表示寻呼号码;加入组件RadioGroup,命名为
RadioGroup1 Caption设为呼机类型,items中加入两项,分别为中文机、数字机;
加入组件Edit 命名为firstName,用于表示发寻呼人的姓;加入组件RadioGroup,
命名为RadioGroup2 Caption设为寻呼人性别,items中加入两项,分别为先生、小姐;
加入组件Memo,命名为callmsg,用于输入发送的信息(注:对于数字机只能是数字信息);
加入组件NMHTTP 命名为NMHTTP1;加入Checkbox,命名为ifuseproxy,用于确定是否使用
代理服务器;加入两个Edit组件,分别用于软件代理服务器地址、代理服务器端口;最后
加入命令按钮 Caption设为“发送”。
现在以国信寻呼为例,它用GET请求就可以实现了“发送”按钮的程序代码如下:
procedure TForm1.Button1Click(Sender: TObject);
var callstr:string;
begin callstr:='http://tips.gxspace.com/cgi-bin/tips/webpaging?stn_id='+callto.Text+'&amp;page_no='+tonumber.Text;
case RadioGroup1.ItemIndex of
0:callstr:=callstr+'&amp;pager_type=C';
1:callstr:=callstr+'&amp;pager_type=N';
end;
callstr:=callstr+'&amp;firstname='+firstname.text;
case RadioGroup2.ItemIndex of
0:callstr:=callstr+'&amp;title=0';
1:callstr:=callstr+'&amp;title=1';
end;
callstr:=callstr+'&amp;msg='+callmsg.Text+'&amp;answer=null&amp;B1=发送寻呼';
NMHTTP1.InputFileMode := FALSE;
NMHTTP1.OutputFileMode := FALSE;
NMHTTP1.ReportLevel := Status_Basic;
If ifuseproxy.Checked then
Begin
NMHTTP1.Proxy := Edit1.Text;
NMHTTP1.ProxyPort := StrToInt(Edit2.Text);
End;
NMHTTP1.Get(callstr);
end;
有些寻呼(如润迅寻呼就不能用上面的GET请求实现,它要用POST请求),使用与上面相差
不大,如下面是NMHTTP的POST用法:
NMHTTP1.InputFileMode:=False;
NMHTTP1.OutputFileMode:=True;
NMHTTP1.ReportLevel:=Status_Basic;
If ifuseproxy.Checked then
Begin
NMHTTP1.Proxy := Edit1.Text;
NMHTTP1.ProxyPort := StrToInt(Edit2.Text);
End;
With NMHTTP1.HeaderInfo do
Begin
Cookie := Edit5.Text;
LocalMailAddress := Edit6.Text;
LocalProgram := Edit7.Text;
Referer := Edit8.Text;
UserID := Edit9.Text;
Password := Edit10.Text;
End;
// 把要提交的数据先放在test.txt文件中:格式为stnid=A&amp;pageno=123456...
NMHTTP1.Post('http://www.wocall.com/script/zbwebcall.asp' 'test.txt');
//NMHTTP的具体用法在Delphi安装目前/Borland/Delphi5/Demos/FastNet/Http下有个
NMHTTP使用的例子。
以上都是用NMHTTP实现的,其实用Delphi中的WebBrowser组件同样可以完成数据的提交,
使用是这样的 Webbrowser1.OleObject.Document.FrontPage_Form1.submit();
说明:WebBrowser1是WebBrowser组件的名 Frontpage_Form1是用WebBrowser打开的网页
中的表单名
网页中的表单是这机样的:

......

这样的实现方法就是用程序生成一个已经按用户输入信息生成一个网页,然后通过
WebBrowser1.Navigate(生成的网页) 最后提交到服务器Webbrowser1.OleObject.Document.FrontPage_Form1.submit();
这样就完成了一次寻呼
 
兄弟谢谢你,
但我要的是网上发手机短讯,而不是寻呼机的
 
首先你得找一个运营商,现在中国就联通和移动,以后可能电信的小灵通会加入。其中联通的是SGIP协议,移动的是CCMP协议,都是基于SMPP协议基础上进行扩充的。你找他们申请成为他们的SP,当然这是需要一定条件的。
好了,他们会提供一些信息给你的,应该包括一个DLL和相关的一些文档,如果申请成功了,还会包含你们企业代码,短信网关地址,登陆用户名和密码。
OK,利用DLL提供的函数把短信发送到短信网关吧,剩下的事情就由移动和联通搞定吧。当然如果你够牛,可以自己写底层的SOCKET来完成发送短信的功能,呵呵
 
谢谢你们!
结贴
 
后退
顶部