如何通过Com口接数据线把短信息发送到手机上?(50分)

  • 主题发起人 主题发起人 fly_hong_924
  • 开始时间 开始时间
F

fly_hong_924

Unregistered / Unconfirmed
GUEST, unregistred user!
unit uSendSms;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, OleCtrls, MSCommLib_TLB;

type
TFrmSendSms = class(TForm)
Label1: TLabel;
Edit1: TEdit;
Label2: TLabel;
Memo1: TMemo;
Button1: TButton;
Button2: TButton;
MSComm: TMSComm;
Label3: TLabel;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Memo1Change(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
function OpenPort() : Boolean;
// procedure SendSMS(lst : TList; Mobile : string); // 将 lst 中的邮件编辑短信发送到手机
procedure SendSMS(Mobile : string;SmsMsg:WideString); // 将 lst 中的邮件编辑短信发送到手机
procedure IniSMS(); // 初始化短消息
procedure SendInEncodeText(sms : string; mobile : string); // Text mode
procedure SendInEncodePdu(sms : string; mobile : string); // pdu mode
function EncodeGb(var s: WideString): String;
function ExchangeCode(src: string): string;
end;

var
FrmSendSms: TFrmSendSms;

implementation

uses Config;

{$R *.dfm}

procedure TFrmSendSms.Button1Click(Sender: TObject);
begin
Application.CreateForm(TfrmConfig,frmConfig);
frmConfig.ShowModal;
frmConfig.Free;
MSComm.CommPort := Config.m_Com.m_ComPort;
MSComm.Settings := Config.m_Com.m_BaudRate + ',' + Copy(Config.m_Com.m_Parity, 0, 1) + ',' + Config.m_Com.m_DataBits + Config.m_Com.m_StopBits;
end;

// 将中文GB2312编码转换为代码页为CP936的Unicode编码
function TFrmSendSms.EncodeGb(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;
// 用来交换移位
function TFrmSendSms.ExchangeCode(src: string): string;
var
Len, i : integer;
tmp : string;
begin
Len := length(src);
if (len <> 11) and (len <> 13) then
begin
ExchangeCode := '';
exit;
end;
src := src + 'F';

i := 1;
while i<=len do
begin
tmp := tmp + src[i + 1] + src;
inc(i, 2);
end;
ExchangeCode := tmp;
end;

procedure TFrmSendSms.IniSMS;
var
SendData : string;
begin
// 先判断串口是否打开
if not MSComm.PortOpen then
exit;
// 设置编码模式,其中Text=1, pdu = 0
if Config.m_Config.m_SMSMode = 'Text' then
SendData := 'AT+CMGF=1' + chr(13) // Text
else
SendData := 'AT+CMGF=0' + chr(13); // Pdu
MSComm.Output := SendData;
// 设置短信中心号码
// SendData := 'AT+CSCA="' + Config.m_Config.m_SMSCenter + '"' + chr(13); //2004-05-01
SendData := 'AT+CSCA' +chr(13);
// Showmessage(SendData);
MSComm.Output := SendData;
end;

function TFrmSendSms.OpenPort: Boolean;
begin
// 更新MSComm的设置
try
MSComm.CommPort := Config.m_Com.m_ComPort;
MSComm.Settings := Config.m_Com.m_BaudRate + ',' + Copy(Config.m_Com.m_Parity, 0, 1) + ',' + Config.m_Com.m_DataBits + Config.m_Com.m_StopBits;
MSComm.InBufferSize := 1024; // 指定接收缓冲区大小
MSComm.InBufferCount := 0; // 清空接收缓冲区
MSComm.InputMode := 1; // 设置数据获取方式
MSComm.InputLen := 0; // 设置读取方式
MSComm.PortOpen := True; // 打开指定的串口
OpenPort := MSComm.PortOpen; // 反回值
except
OpenPort := False;
MessageBox(self.Handle, PChar('串口' + PChar(IntToStr(Mscomm.CommPort)) + '打开失败!,请更换其它串口'),'串口打开失败',MB_OK);
end;
end;
// Pdu模式编码
procedure TFrmSendSms.SendInEncodePdu(sms, mobile: string);
var
Widesms : WideString; // 定义成WideString型,每个字符占两上字节
SendData : string;
tmp : string;
len : integer;
begin
// 参考pdu串 08 91 683108701305F0 11 00 0B 91 3176378290F9 00 00 00 02 C834
SendData := 'AT+CMGS="';
SendData := SendData + '0891';
// 每两位交换构造短信中心串
// tmp := ExchangeCode(Config.m_Config.m_SMSCenter); 2004-05-01
SendData := SendData + tmp;
SendData := SendData + '11000B91';
// 每两位交换构造接收手机号码串
tmp := ExchangeCode(mobile);
SendData := SendData + tmp;
SendData := Senddata + '0000A7';
// 将中文GB2312编码转换为代码页为CP936的Unicode编码
Widesms := WideString(sms);
tmp := EncodeGb(Widesms);
// 此处为Widesms 的长度,不是sms的长度!
len := length(Widesms);
SendData := SendData + IntToStr(len) + tmp;
SendData := SendData + '"' + chr(13);
// Pdu串构造完毕,发送
MSComm.Output := SendData;
end;
// Text模式编码
procedure TFrmSendSms.SendInEncodeText(sms, mobile: string);
var
strOut : string; // 定义成string型,一个字符用一个字节来表示
begin
strOut := 'AT+CMGS="' + mobile + '"' + chr(13); // chr(13)是回车
MSComm.Output := strOut;
strOut := sms + chr(26); // chr(26) 是 ctrl + z
MSComm.Output := strOut;
end;

procedure TFrmSendSms.SendSMS(Mobile:string;SmsMsg:WideString);
var
i : integer;
strSMS : string;
begin
// 加入发送短消息日志
if length(Mobile) <> 11 then
begin
ShowMessage('目标手机号不正确,发送短信失败!');
exit;
end;
if length(Config.m_Config.m_SMSCenter) <> 13 then
begin
ShowMessage('短信中心地址不正确,发送短信失败!');
exit;
end;
// 打开端口
if not OpenPort() then
exit;
// 初始化短消息,指定编码模式和短消息中心地址
IniSMS();
// for i := 0 to lst.Count - 1 do
begin
if Config.m_Config.m_SMSMode = 'Text' then
begin
strSMS :=SmsMsg;//Memo1.Lines.Text;
SendInEncodeText(strSMS, Mobile);
end
else
begin
strSMS :=SmsMsg;//Memo1.Lines.Text;
SendInEncodePdu(strSMS, Mobile);
end;
end;
// 关闭串口
MSComm.PortOpen := False;
end;

procedure TFrmSendSms.Button2Click(Sender: TObject);
begin
if Trim(edit1.Text)='' then
begin
Application.MessageBox('手机号码不能为空,请重新输入!','提示信息',$40);
edit1.SetFocus;
Abort;
end;
if Trim(Memo1.Text)='' then
begin
Application.MessageBox('没有可发送的短信内容,请重新输入!','提示信息',$40);
Memo1.SetFocus;
Abort;
end;

SendSMS(edit1.Text,Memo1.Text);
end;

procedure TFrmSendSms.Memo1Change(Sender: TObject);
var
strMemo:WideString;
begin
StrMemo:=Memo1.Text;
Label3.Caption:='字符数:'+IntToStr(Length(StrMemo));
end;

end.
这是我在一些地方查到的一些代码。究竟要怎样才能通过Com口的数据线把信息发送到手机来???希望能得到大家的帮忙。
 
怎么都没有人能回答????没有人做过这方面的?
 
这么多天了都没有人能回答的?是不是分数太少了。如果分数不够,我再加。。。
 
??手机得支持才行吧?支持,知道了协议,就可以写代码了。
 
发短信需要通信公司的网关和DLL,不是随便都可以发的。
当然也可以通过红外连一个手机,不过很麻烦,也不实用。
 
用串口发手机,除非有手机MODEM,好象是2000的样子
 
手机modem是什么来的?是不是要另外购买的一个硬件阿?但我买手机的时候,已经有一条数据通信线,它自带有一个软件,只是发铃声的。我就是想试一下怎么把短信直接通过这线发到手机去。欢迎大家继续来探讨此问题……
 
我之前也写过。现在还在用住。
手机先要能和你的串口进行通迅。能执行一些指令。比如at at+cgmi 等等。
然后再考虑你能发你的东西出去。
 
这是我里面主要的一些代码。你看看

{
-----------------------------------------------------------
GB 代码转 UniCode
-----------------------------------------------------------
//功能:中文字符串变化到Unicode字符串
//输入: txt-中文字符串
//输出: 转化成Unicode的字符串
}

function TFrmMain.str_Gb2UniCode(text: string): string;
var
i, j, len: Integer;
cur: Integer;
t: string;
ws: WideString;
begin
Result := '';
ws := text;
len := Length(ws);
i := 1;
j := 0;
while i <= len do
begin
cur := ord(ws);
FmtStr(t, '%4.4X', [cur]); //BCD转换
Result := Result + t;
inc(i);
//移位计数达到7位的特别处理
j := (j + 1) mod 7;
end;
end;

//将一个字符串在位置上进行奇数位与偶数位的交换,字符串长度为奇数位时自动补F
//如果12345转换后为 2143F5

function TFrmMain.ConvertL2R(sMsg: string): string;
var i: Integer;
cTmp: Char;
sRe: string;
begin
sRe := Trim(sMsg);
i := Length(sRe);
if i = 0 then
begin
Result := '';
Exit;
end;

if i mod 2 = 1 then
sRe := sRe + 'F';

i := 1;
while i < Length(sRe) do
begin
cTmp := sRe;
sRe := sRe[i + 1];
sRe[i + 1] := cTmp;
i := i + 2;
end;

Result := sRe;
end;

//txt转换为pdu格式
//不带加号短信息中心号码、手机号码、短信内容
//如 sms := TextToPdu( '8613800755500', '13682570067', '你好',a,b );
//返回可直接发送的字符串代码

function TFrmMain.TextToPdu(sCenter, sPhone, sMsg: string; var a: string; var b: string): boolean;
var sAddr, sBody: string;
LCenter, LMsg, LBody: string;
begin
sCenter := '91' + ConvertL2R(sCenter);
FmtStr(LCenter, '%2.2X', [Length(sCenter) div 2]);
sAddr := LCenter + sCenter;

sPhone := ConvertL2R(sPhone);
sMsg := str_Gb2UniCode(sMsg);
FmtStr(LMsg, '%2.2X', [Length(sMsg) div 2]);

sBody := '11000D9168' + sPhone + '000800' + LMsg + sMsg;
FmtStr(LBody, '%2.2D', [Length(sBody) div 2]);
a := 'AT+CMGS=' + LBody + #13; //要发送的长度
b := sAddr + sBody + #26 + #13; //要发送的pdu代码
Result := true;

end;

发送串口数据时,先要发送a(短信长度)指令给手机,然后再发送b(内容)指令给手机。
 
必须由电信运营商提供的接口才可以,不然每个人都可以用软件发送短信,那电信不是跨了吗???
 
怎样去电信申请,要多少钱啊?
 
http://www.ccw.com.cn/htm/net/seminar/02_1_22_4.asp

gsm的已经实现,但是cdma的还没有搞成,有谁知道的出声。
 
到这里去看一下有没有收获
www.mobset.com
 
你们是不是都弄错意思了?我的意思是通过数据线把信息发到手机,不需要经过短信中心的。主要一点就是com口数据发送出去后,接在com口的手机怎么接受这个数据?
 
呵呵,这个太EASY了~
楼主看看我的软件吧~
http://www.GhostSoft.net

发送数据的时候需要按照手机的AT指令格式来发送。
例如,先发送一个通知手机要我发送短消息的AT指令,
然后等待手机做出回应后再把编码后的短信内容(包括收件人号码,短信中心号码等内容)发过去。
 
你的这段代码肯定是使用GSM短信模块的通讯程序,你需要在在串口上连接一个AT命令界面的GSM模块(如TC35)或带数据接口的手机
 
To Delphi哈哈王 有没有具体的一些代码?我上面的代码有没有问题,请指教……
 
需要AT指令,大富翁上原来发过贴子,你搜一下啊,离线数据包
 
to fly_hong_924:
你可以先发送一个“AT+CMGS=?”AT指令到手机,如果返回OK,则表示你手机支持这个命令。
你上面给出的代码理论上来说是对的,我没测试,不知道你代码的PDU 编码部分是否正确。
其实最关键的是PDU的编码,编码正确了,发送到手机就可以正常发送了。
我的QQ:12003356,
有问题找我。
 
后退
顶部