手机短信收发问题(十万火急)(100分)

  • 主题发起人 主题发起人 lht123
  • 开始时间 开始时间
L

lht123

Unregistered / Unconfirmed
GUEST, unregistred user!
我现在在开发手机短信系统,我用spcomm控件读,写串口,用Comm2.WriteCommData事件发at命令给串口,用Comm2ReceiveData接收手机发给gprs模块的数据,当有很多人给我的模块发数据的时候,我必须把这些数据送到我的数据库了.保证数据不能丢失,我的模块卡里的存储容量有限,我想从卡里读出一条数据后,就清空,但是我怕把其他人的数据也清空了,现在我的程序是这么实现的---我先用 AT+CPMS? 判断卡里有几条数据,读出短信的索引,根据索引发AT+CMGR=索引号,把短信都读出来,在把卡里的数据清掉,用AT+CMGD=1,3 命令,我现在很担心用最好一条命令会出错,另外我用timer控件发 at命令,我想怎么做才能很安全的把数据读到,当卡里的数据满了后 ,清空,在去收数据.timer控件每次调用都占用焦点,很烦人,大侠们是怎么做的,自动发送at命令 去读卡里的数据.我现在头都大了,用了两个timer控件,都变成死循环了,求求你们帮帮我,分不够再加.
 
1.你应该使用线程而不要使用Timer控件。
2.你可以一条一条删除短信呀?为什么要一起全部删除呢?
 
to xxhadsg 你的建议很好,但是用线程怎么做呢,怎么去发at命令,多长时间发一次,怎么做,线成我没做过,用几个线成做啊,谢谢了,帮帮我吧
 
我采用的是消息到达提示,收到消息后自动转存到临时文件中,对临时文件处理!
 
兄弟们,在给我支招啊
 
不要用AT+CMGD=1,3 ,还是读一条然后把读取的这条删除比较好。象xxhadsg说的那样,用线程来处理吧,一个读数据的一个发AT指令的。GOOD LUCK!
 
把用timer控件改为消息
 
我也在做这个,我毕业设计就是短信平台开发这个题目,但是我实在不懂楼主你的问题,支持一下吧!!
 
我毕设也是做短信平台,您有这方面的资料没.
给我发一个啊!
Email:accsx@163.com
 
lht123大人,借用宝地,谢谢(新注册的帐号,以前的帐号忘记密码了,见谅,谢谢)

我是大四学生,做毕业设计用delphi 7开发短信平台,由于不懂理论,也找不到相关的书籍,所以做的很不顺利,从网上下载的源代码也看不懂,只能看懂个大概,具体原理还是看不懂,很闹心很闹心,希望大家能帮我.

我的delphi源代码如下:(是网上广为流传的代码,利用新浪网关收发短信的平台)
implementation

uses SendCodeInfo, RecCodeInfo;

{$R *.dfm}

function Tfrmsend.CheckCode(sCode:string):boolean;
var
i:integer;
begin
if(Trim(sCode)='') then
begin
Result:=false;
Exit;
end;
if(Length(Trim(sCode))<>11) then
begin
Result:=false;
Exit;
end;
for i:=1 to 11 do
begin
if not (Copy(sCode,i,1)[1] in ['0','1','2','3','4','5','6','7','8','9']) then
begin
Result:=false;
Exit;
end;
end;
Result:=true;
end;

procedure TfrmSend.FreeData;
var
i:integer;
begin
for i:=0 to cmbSendCode.Items.Count-1 do
begin
if(PSendCodeInfo(cmbSendCode.Items.Objects)<>nil) then
Dispose(PSendCodeInfo(cmbSendCode.Items.Objects));
end;
for i:=0 to cmbRecCode.Items.Count-1 do
begin
if(PRecCodeInfo(cmbRecCode.Items.Objects)<>nil) then
Dispose(PRecCodeInfo(cmbRecCode.Items.Objects));
end;
for i:=0 to cmbMsgList.Items.Count-1 do
begin
if(PMsgInfo(cmbMsgList.Items.Objects)<>nil) then
Dispose(PMsgInfo(cmbMsgList.Items.Objects));
end;
end;

procedure TfrmSend.SaveMsgInfo;
var
i :integer; //循环使用
iMsgCount :integer; //发送号码的位数
sMsgCaption:AnsiString; //号码主人名称
sMsgContent:AnsiString; //号码
strPath :AnsiString; //路径
iniFile :TIniFile; //操作ini文件
sMsg :AnsiString; //发送的消息
begin
strPath:=ExtractFilePath(Application.ExeName)+'SendSMS.ini';
try
iniFile:=TIniFile.Create(strPath);
iniFile.EraseSection('SendMsg');
IniFile.WriteString('SendMsg','MsgCount',IntToStr(cmbMsgList.Items.Count));
for i:=0 to cmbMsgList.Items.Count-1 do
begin
sMsgCaption:=PMsgInfo(cmbMsgList.Items.Objects)^.sMsgCaption;
sMsgContent:=PMsgInfo(cmbMsgList.Items.Objects)^.sMsgContent;
sMsg:=sMsgCaption+'_CC_'+sMsgContent;
IniFile.WriteString('SendMsg','Msg'+IntToStr(i+1),sMsg);
end;
finally
if(iniFile<>nil) then
iniFile.Free;
end;
end;

procedure TfrmSend.ReadMsgInfo;
var
iMsgCount :integer;
i :integer;
iCC :integer;
sMsgCaption:AnsiString;
sMsgContent:AnsiString;
iniFile :TIniFile;
strPath :AnsiString;
sMsg :AnsiString;
MsgInfo :PMsgInfo;
begin
strPath:=ExtractFilePath(Application.ExeName)+'SendSMS.ini';
try
iniFile:=TIniFile.Create(strPath);
iMsgCount:=iniFile.ReadInteger('SendMsg','MsgCount',0);
for i:=1 to iMsgCount do
begin
sMsg:=iniFile.ReadString('SendMsg','Msg'+IntToStr(i),'');
iCC:=Pos('_CC_',sMsg);
sMsgCaption:=Copy(sMsg,1,iCC-1);
sMsgContent:=Copy(sMsg,iCC+4,Length(sMsg)-iCC-3);
New(MsgInfo);
MsgInfo.sMsgCaption:=sMsgCaption;
MsgInfo.sMsgContent:=sMsgContent;
cmbMsgList.Items.AddObject(sMsgCaption,TObject(MsgInfo));
end;
finally
if(iniFile<>nil) then
iniFile.Free;
end;
end;

procedure TfrmSend.ReadSendCodeInfo;
var
iSendCount:integer;
i :integer;
iNC :integer;
iCP :integer;
sSendName :AnsiString;
sSendCode :AnsiString;
sPassword :AnsiString;
iniFile :TIniFile;
strPath :AnsiString;
sSend :AnsiString;
SendCodeInfo:PSendCodeInfo;
begin
strPath:=ExtractFilePath(Application.ExeName)+'SendSMS.ini';
try
iniFile:=TIniFile.Create(strPath);
iSendCount:=iniFile.ReadInteger('SendCode','SendCount',0);
for i:=1 to iSendCount do
begin
sSend:=iniFile.ReadString('SendCode','SendCode'+IntToStr(i),'');
iNC:=Pos('_NC_',sSend);
iCP:=Pos('_CP_',sSend);
sSendName:=Copy(sSend,1,iNC-1);
sSendCode:=Copy(sSend,iNC+4,iCP-iNC-4);
sPassword:=Copy(sSend,iCP+4,Length(sSend)-iCP);
New(SendCodeInfo);
SendCodeInfo.sSendCode:=sSendCode;
SendCodeInfo.sSendName:=sSendName;
SendCodeInfo.sPassword:=SPassword;
cmbSendCode.Items.AddObject(sSendName,TObject(SendCodeInfo));
end;
finally
if(iniFile<>nil) then
iniFile.Free;
end;
end;

procedure TfrmSend.ReadRecCodeInfo;
var
iRecCount:integer;
i :integer;
iNC :integer;
iCP :integer;
sRecName :AnsiString;
sRecCode :AnsiString;
iniFile :TIniFile;
strPath :AnsiString;
sRec :AnsiString;
RecCodeInfo:PRecCodeInfo;
begin
strPath:=ExtractFilePath(Application.ExeName)+'SendSMS.ini';
try
iniFile:=TIniFile.Create(strPath);
iRecCount:=iniFile.ReadInteger('ReceiveCode','RecCount',0);
for i:=1 to iRecCount do
begin
sRec:=iniFile.ReadString('ReceiveCode','RecCode'+IntToStr(i),'');
iNC:=Pos('_NC_',sRec);
sRecName:=Copy(sRec,1,iNC-1);
sRecCode:=Copy(sRec,iNC+4,Length(sRec)-iNC-3);
New(RecCodeInfo);
RecCodeInfo.sRecCode:=sRecCode;
RecCodeInfo.sRecName:=sRecName;
cmbRecCode.Items.AddObject(sRecName,TObject(RecCodeInfo));
end;
finally
if(iniFile<>nil) then
iniFile.Free;
end;
end;

procedure TfrmSend.SaveSendCodeInfo;
var
i :integer; //循环使用
iSendCount:integer; //发送号码的位数
sSendName :AnsiString; //号码主人名称
sSendCode :AnsiString; //号码
sPassword :AnsiString; //密码
strPath :AnsiString; //路径
iniFile :TIniFile; //操作ini文件
sSend :AnsiString;
begin
strPath:=ExtractFilePath(Application.ExeName)+'SendSMS.ini';
try
iniFile:=TIniFile.Create(strPath);
iniFile.EraseSection('SendCode');
IniFile.WriteString('SendCode','SendCount',IntToStr(cmbSendCode.Items.Count));
for i:=0 to cmbSendCode.Items.Count-1 do
begin
sSendName:=PSendCodeInfo(cmbSendCode.Items.Objects)^.sSendName;
sSendCode:=PSendCodeInfo(cmbSendCode.Items.Objects)^.sSendCode;
sPassword:=PSendCodeInfo(cmbSendCode.Items.Objects)^.sPassword;
sSend:=sSendName+'_NC_'+sSendCode+'_CP_'+sPassword;
IniFile.WriteString('SendCode','SendCode'+IntToStr(i+1),sSend);
end;
finally
if(iniFile<>nil) then
iniFile.Free;
end;
end;

procedure TfrmSend.SaveRecCodeInfo;
var
i :integer; //循环使用
iRecCount:integer; //发送号码的位数
sRecName :AnsiString; //号码主人名称
sRecCode :AnsiString; //号码
strPath :AnsiString; //路径
iniFile :TIniFile; //操作ini文件
sRec :AnsiString;
begin
strPath:=ExtractFilePath(Application.ExeName)+'SendSMS.ini';
try
iniFile:=TIniFile.Create(strPath);
iniFile.EraseSection('ReceiveCode');
IniFile.WriteString('ReceiveCode','RecCount',IntToStr(cmbRecCode.Items.Count));
for i:=0 to cmbRecCode.Items.Count-1 do
begin
sRecName:=PRecCodeInfo(cmbRecCode.Items.Objects)^.sRecName;
sRecCode:=PRecCodeInfo(cmbRecCode.Items.Objects)^.sRecCode;
sRec:=sRecName+'_NC_'+sRecCode;
IniFile.WriteString('ReceiveCode','RecCode'+IntToStr(i+1),sRec);
end;
finally
if(iniFile<>nil) then
iniFile.Free;
end;
end;

function TfrmSend.DeleteCR(s:string):string;
var
i:integer; //循环使用
begin
i:=Pos(#$d,s);
while i<>0 do
begin
Delete(s,i,1);
i:=Pos(#$d,s);
end;
i:=Pos(#$a,s);
while i<>0 do
begin
Delete(s,i,1);
i:=pos(#$a,s);
end;
Result:=s;
end;

procedure TfrmSend.btnSendClick(Sender: TObject);
var
ovTargetFrameName:OleVariant;
ovPostData :OleVariant;
ovFlags :OleVariant;
ovHeads :OleVariant;
begin
if(cmbRecCode.ItemIndex=-1) then
begin
MessageBox(Handle,'选择接收的号码!','提示信息',MB_OK);
Exit;
end;
if(CheckCode(PRecCodeInfo(cmbRecCode.Items.Objects[cmbRecCode.ItemIndex])^.sRecCode)=false) then
begin
MessageBox(Handle,'接收号码不正确!','提示信息',MB_OK);
Exit;
end;
if(cmbSendCode.ItemIndex=-1) then
begin
MessageBox(Handle,'选择发送的号码!','提示信息',MB_OK);
Exit;
end;
if(CheckCode(PSendCodeInfo(cmbSendCode.Items.Objects[cmbSendCode.ItemIndex])^.sSendCode)=false) then
begin
MessageBox(Handle,'发送号码不正确!','提示信息',MB_OK);
Exit;
end;
if(Trim(memSendContent.Text)='') then
begin
MessageBox(Handle,'输入发送的内容!','提示信息',MB_OK);
memSendContent.SetFocus;
Exit;
end;
iSendSMS:=0;
ovTargetFrameName:=0;
ovPostData:=0;
ovHeads:=0;
ovFlags:=0;
wbSendSMS.Navigate('http://sms.sina.com.cn/docs/send.html',
ovFlags,ovTargetFrameName,ovPostData,ovHeads);
sbSendSMS.Panels.Items[0].Text:='正在发送...';
end;

procedure TfrmSend.btnCancelClick(Sender: TObject);
begin
wbSendSMS.Stop;
//Close;
end;

procedure TfrmSend.wbSendSMSDocumentComplete(Sender: TObject;
const pDisp: IDispatch; var URL: OleVariant);
var
i :integer; //循环使用
iInputCount:integer; //计算<Input> 的次数
ovDoc :OleVariant; //取得网页的内容
sSendCode :AnsiString; //发送手机号码
sPassword :AnsiString; //发送短消息的密码
sRecCode :AnsiString; //接收代码
begin
case iSendSMS of
0:
begin
Inc(iSendSMS);
ovDoc:=(Sender as TWebBrowser).Document;
iInputCount:=0;
for i:=0 To ovDoc.All.Length-1 do
begin
if (ovDoc.All.Item(i).tagName = 'TEXTAREA')and //一定大写
(ovDoc.All.Item(i).name='msg')then //大小写与原文一致
begin
ovDoc.All.Item(i).Value:=DeleteCR(memSendContent.Lines.Text);
Inc(iInputCount);
end;
if (ovDoc.All.Item(i).tagName = 'INPUT')and //一定大写
(ovDoc.All.Item(i).type='text')and //大小写与原文一致
(ovDoc.All.Item(i).Name='mob1')then
begin
sRecCode:=PRecCodeInfo(cmbRecCode.Items.Objects[cmbRecCode.ItemIndex])^.sRecCode;
ovDoc.All.Item(i).Value:=Trim(sRecCode);
Inc(iInputCount);
end;
if (ovDoc.All.Item(i).tagName = 'INPUT')and //一定大写
(ovDoc.All.Item(i).type='text')and //大小写与原文一致
(ovdoc.All.Item(i).Name='user')then
begin
sSendCode:=PSendCodeInfo(cmbSendCode.Items.Objects[cmbSendCode.ItemIndex])^.sSendCode;
ovDoc.All.Item(i).Value:=Trim(sSendCode);
Inc(iInputCount);
end;
if (ovDoc.All.Item(i).tagName = 'INPUT')and //一定大写
(ovDoc.All.Item(i).type='password')and //大小写与原文一致
(ovDoc.All.Item(i).Name='passwd')then
begin
sPassword:=PSendCodeInfo(cmbSendCode.Items.Objects[cmbSendCode.ItemIndex])^.sPassword;
ovDoc.All.Item(i).Value:=Trim(sPassword);
Inc(iInputCount);
end;
if (ovDoc.All.Item(i).tagName = 'INPUT')and //一定大写
(ovDoc.All.Item(i).type='submit')and //大小写与原文一致
(ovDoc.All.Item(i).value=' 发送 ')then
begin
if iInputCount=4 then
ovDoc.All.Item(i).Click;
Inc(iInputCount);
end;
end;
end;
1:
begin
ovDoc:=(Sender as TWebBrowser).Document;
Inc(iSendSMS);
if(Pos('发送成功',ovDoc.All.item.innerhtml)<>0) then
sbSendSMS.Panels.Items[0].Text:='发送成功'
else
sbSendSMS.Panels.Items[0].Text:='发送失败';
end;
end;
end;

procedure TfrmSend.sbSaveSendCodeClick(Sender: TObject);
begin
frmSendCodeInfo:=TfrmSendCodeInfo.Create(Self);
frmSendCodeInfo.ShowModal;
frmSendCodeInfo.Free;
end;

procedure TfrmSend.sbSaveRecCodeClick(Sender: TObject);
begin
frmRecCodeInfo:=TfrmRecCodeInfo.Create(Self);
frmRecCodeInfo.ShowModal;
frmRecCodeInfo.Free;
end;

procedure TfrmSend.memSendContentChange(Sender: TObject);
begin
memSendContent.Text:=DeleteCR(memSendContent.Lines.Text);
end;

procedure TfrmSend.sbDeleteRecCodeClick(Sender: TObject);
begin
cmbRecCode.DeleteSelected;
SaveRecCodeInfo;
end;

procedure TfrmSend.sbDeleteSendCodeClick(Sender: TObject);
begin
cmbSendCode.DeleteSelected;
SaveSendCodeInfo;
end;

procedure TfrmSend.FormCreate(Sender: TObject);
begin
ReadSendCodeInfo;
ReadRecCodeInfo;
ReadMsgInfo;
end;

procedure TfrmSend.cmbRecCodeChange(Sender: TObject);
begin
if(cmbRecCode.ItemIndex<>-1) then
begin
sbSendSMS.Panels.Items[1].Text:='接收:'+PRecCodeInfo(cmbRecCode.Items.Objects[cmbRecCode.ItemIndex])^.sRecCode;
end;
end;

procedure TfrmSend.cmbSendCodeChange(Sender: TObject);
begin
if(cmbSendCode.ItemIndex<>-1) then
begin
sbSendSMS.Panels.Items[2].Text:='发送:'+PSendCodeInfo(cmbSendCode.Items.Objects[cmbSendCode.ItemIndex])^.sSendCode;
end;
end;

procedure TfrmSend.sbDeleteMsgClick(Sender: TObject);
begin
cmbMsgList.DeleteSelected;
SaveMsgInfo;
end;

procedure TfrmSend.sbSaveMsgClick(Sender: TObject);
var
sMsgCaption:AnsiString;
sMsgContent:AnsiString;
MsgInfo:PMsgInfo;
begin
if(Trim(cmbMsgList.Text)='') then
begin
cmbMsgList.SetFocus;
MessageBox(Handle,'输入消息标题','提示信息',MB_OK);
Exit;
end;
if(Trim(memSendContent.Text)='') then
begin
memSendContent.SetFocus;
MessageBox(Handle,'没有消息内容!','提示信息',MB_OK);
Exit;
end;
if(cmbMsgList.Items.IndexOf(Trim(cmbMsgList.Text))<>-1) then
begin
if(MessageBox(Handle,'已经有此消息!,继续加入以此标题的消息?','提示信息',MB_YESNO)=IDNO) then
Exit;
end;
sMsgCaption:=Trim(cmbMsgList.Text);
sMsgContent:=Trim(memSendContent.Text);
New(MsgInfo);
MsgInfo.sMsgCaption:=sMsgCaption;
MsgInfo.sMsgContent:=sMsgContent;
cmbMsgList.Items.AddObject(sMsgCaption,TObject(MsgInfo));
SaveMsgInfo;
end;

procedure TfrmSend.cmbMsgListChange(Sender: TObject);
begin
if(cmbMsgList.ItemIndex<>-1) then
begin
memSendContent.Lines.Clear;
memSendContent.Text:=PMsgInfo(cmbMsgList.Items.Objects[cmbMsgList.ItemIndex])^.sMsgContent;
end;
end;

procedure TfrmSend.FormDestroy(Sender: TObject);
begin
FreeData;
end;

procedure TfrmSend.lblTSClick(Sender: TObject);
begin
ShellExecute(Handle,'open','http://sms.sina.com.cn/docs/term2.html',nil,nil,SW_SHOWNORMAL);
end;

end.


希望大家能在白忙中抽出时间帮我看看这段代码,帮我分析分析采用的什么原理,可能这个代码并不是最好的,各位高手们或许以前也做过短信平台开发的,如果你们有更好的实现方法,请给以指点,谢谢!!
我的QQ是250684246,大家有什么好的意见可以在网上告诉我;或者有什么好的资料可以传给我或者发送到我的邮箱:jmsw1984@163.com,最后谢谢大家了!
 
上面的代码是使用短信网关发送的,你必须要通过sina往外发送,所以与楼主的问题不太一样。通过网关发送你只要调用相关函数或提交相关信息就可以了,如果使用ISP的网关发送那就要遵循各ISP[联通或一移动等]的开发协议。
/*
to xxhadsg 你的建议很好,但是用线程怎么做呢,怎么去发at命令,多长时间发一次,怎么做,线成我没做过,用几个线成做啊,谢谢了,帮帮我吧
*/
我使用的是一个队列,将所有要处理的命令加入这个队列中进行排队。线程就处理这个队列,如果队列中的有待处理的命令,就调出执行,没有的话就让线程等待。

有这么多人找资料,其实网上可以搜索到许多,AT指令各GSM模块基本相同,但也有差异,各ISP网关的协议也不一样,需要的朋友我放到网站上,去下载吧。
http://www.tinstec.com
 
to jmsw 我不是通过网关接收数据的,我是用sim卡接收,我在看消息处理函数和线程呢,看来只能这么做了,timer控件真不稳定!!!有做过和我类似的系统的,给我点建议,谢谢了.
 
多人接受答案了。
 
后退
顶部