串口编程 解析接收的短消息 ( 积分: 20 )

  • 主题发起人 主题发起人 mawei0913_green
  • 开始时间 开始时间
M

mawei0913_green

Unregistered / Unconfirmed
GUEST, unregistred user!
最近在做一个关于短消息的编程,当用户发一条短信给Gsm modem时,modem根据发的内容,将从数据库中读取相应的内容,然户将相应的内容以一条短信的形式发送给用户。可是当输入短信长度小于<=7时,可以完全读取用户发来的内容,例如&quot;1411103&quot;,它显示1411103,但是当输入的短信长度>7时,不能完全读取用户发来的信息,例如&quot;14111038&quot;,它只显示1411103,后面的8没有读取出来,也就是说短消息只要大约>7的长度,它就不能完全读取。
下面菜鸟将用到的代码列出来,请各位高人帮忙,谢谢!!

//解析接收的消息,s是接收的短信
//oa是手机号,rd是接收的日期,ud代表接收到的内容
function TForm_Main.DecodeRecvData(head, s: string): Boolean
var
len : string;
reclen : string;
t : string;
i, l : Integer;
oa : string; //源地址
ud : string; //用户信息
rd: string;
ct : Integer;
Str : String;
iThird : Integer;
begin
if s <> '' then
begin
t := s;
iThird := 16;
repeat
Str := Copy(t,iThird,1);
iThird := iThird + 1;
until
Str = '0';
reclen := Copy(t,iThird - 1,Length(t) - 8 - iThird+2);
t := reclen;
len := '$' + Copy(t, 1, 2); //短信中心号码长度
i := 1 + 2 + 2 * StrToInt(len); //忽略短信中心号码
//效验接收长度是否正确
i := i + 2; //忽略
l := StrToInt('$' + Copy(t, i, 2)); //源地址长度

l := ((l div 2) + (l mod 2)) * 2;
i := i + 2;
i := i + 2; //忽略源地址类型
oa := TelNumDecode(Copy(t, i, l));
i := i + l;
i := i + 2; //忽略协议类型
ct := StrToInt('$' + Copy(t, i , 2)); //编码类型
i := i + 2;
rd := TimeStampDecode(Copy(t, i, 12));
i := i + 12;
i := i + 2; //忽略时区
len := '$' + Copy(t, i, 2);
i := i + 2;
ct := (ct and $0c) shr 2;
if ct = 2 then
ud := USC2Decode(Copy(t, i, StrToInt(len) * 3))
else if ct = 0 then
ud := GsmAlphabetDecode(Copy(t, i, StrToInt(len) * 3))
else
ud := Copy(t, i, StrToInt(len) * 2);
end;
WriteToLog('接收:' + oa + ',' + rd + ',' + ud);
Deal.ParseNote(oa,rd,ud);//oa是手机号,rd是接收的日期,ud代表接收到的内容
end;
菜鸟想问的就是这个ud,不能完全读取出来,请各位高人帮忙看看,本人在这里先谢过啦!
 
怎么没有高人回答呀,串口通讯的程序,请各位高人帮帮忙,给菜鸟指点一下
 
最近在做一个关于短消息的编程,当用户发一条短信给Gsm modem时,modem根据发的内容,将从数据库中读取相应的内容,然户将相应的内容以一条短信的形式发送给用户。可是当输入短信长度小于<=7时,可以完全读取用户发来的内容,例如&quot;1411103&quot;,它显示1411103,但是当输入的短信长度>7时,不能完全读取用户发来的信息,例如&quot;14111038&quot;,它只显示1411103,后面的8没有读取出来,也就是说短消息只要大约>7的长度,它就不能完全读取。
下面菜鸟将用到的代码列出来,请各位高人帮忙,谢谢!!
 
我有成熟的短信接收发送代码。
QQ:417961930!
 
谢了,如果您能解决我上面的问题,本人将购买您的源代码,还请高人指教
 
各位高人,都在看菜鸟的问题吗?还高人指教,有高人会串口通讯吗?帮忙解决一下,谢谢
 
再往底层查查,是不是也丢了,串口通信有个问题,就是响应不是立即的(和串口速率没关系)
举例说:通过串口往设备发个命令,然后等设备响应,这个响应有个时间延迟。表现在代码中就是WRITE完后,马上去READ,则往往不能收到全部数据,一般要延迟段时间再READ,才能收完全的数据。当然这个和串口实现方式或使用串口通信组件有关。一般串口组件中的ONRXCHAR中,如果不延迟,也会收不到完整数据。
如果要快速响应,自己用API写吧。
 
to:janker
还想高人指教
 
function TSMSComm.DecodeChinese(Msg: string): string;
var
i,len,j:Integer;
t: string;
begin
Result:='';
len:=Length(Msg);
i:=1;
while i<=len do begin
t:=Copy(Msg,i,4);
j:=StrToInt('$'+t);
t:=widechar(j);
Result:=Result+t;
i:=i+4;
end;
end;

//7bit解码
function TSMSComm.DecodeSevenBit(Msg: string): string;
var
nSrc: Integer; // 源字符串的计数值
nByte: Byte; // 当前正在处理的组内字节的序号,范围是0-7
nLeft: Byte; // 上一字节残余的数据
begin
Result := '';
nSrc := 1; // 计数值初始化

// 组内字节序号和残余数据初始化
nByte := 0;
nLeft := 0;

// 将源数据每7个字节分为一组,解压缩成8个字节
// 循环该处理过程,直至源数据被处理完
// 如果分组不到7字节,也能正确处理
while nSrc<=Length(Msg) do begin
// 将源字节右边部分与残余数据相加,去掉最高位,得到一个目标解码字节
Result := Result + Chr( ( (Byte(Msg[nSrc]) shl nByte) or nLeft ) and $7F );
// 将该字节剩下的左边部分,作为残余数据保存起来
nLeft := Byte(Msg[nSrc]) shr (7-nByte);

// 修改字节计数值
Inc(nByte);

// 到了一组的最后一个字节
if nByte = 7 then begin
// 额外得到一个目标解码字节
Result := Result + Chr(nLeft);

// 组内字节序号和残余数据初始化
nByte := 0;
nLeft := 0;
end;

// 修改计数值
Inc(nSrc);
end;
end;

//7bit编码
function TSMSComm.EncodeSevenBit(Msg: string): string;
var
nSrc: Integer; // 源字符串的计数值
nByte: Byte; // 当前正在处理的组内字节的序号,范围是0-7
nLeft: Byte; // 上一字节残余的数据
begin
Result := '';
nSrc := 0; // 计数值初始化
nByte := 0;
nLeft := 0;

// 将源串每8个字节分为一组,压缩成7个字节
// 循环该处理过程,直至源串被处理完
// 如果分组不到8字节,也能正确处理
while nSrc<Length(Msg) do begin
// 取源字符串的计数值的最低3位
nByte := nSrc and 7;

// 处理源串的每个字节
if nByte = 0 then
// 组内第一个字节,只是保存起来,待处理下一个字节时使用
nLeft := Byte(Msg[nSrc+1])
else begin
// 组内其它字节,将其右边部分与残余数据相加,得到一个目标编码字节
Result := Result + Chr( (Byte(Msg[nSrc+1]) shl (8-nByte)) or nLeft );
// 将该字节剩下的左边部分,作为残余数据保存起来
nLeft := Byte(Msg[nSrc+1]) shr nByte;
end;

// 修改源串计数值
Inc(nSrc);
end;

if (Length(Msg)>0) and (nByte<>7) then
Result := Result + Chr(nLeft);
end;

// 内码转换
function TSMSComm.CodeMsg(const Msg: string; var DecodeLen: Integer): string;
var
i, Tollen, cur:Integer;
t: string;
TmpWideStr: WideString;
begin
Result:='';
case FEncodeStyle of
esUnicode: begin
TmpWideStr := Msg;
Tollen := Length(TmpWideStr);
i:=1;
while i<=Tollen do
begin
cur := ord(TmpWideStr);
//BCD转换
FmtStr(t, '%4.4X', [cur]);
Result := Result+t;
inc(i);
end;
DecodeLen := Length(TmpWideStr)*2;
end;
esEightBit: begin
for i:=1 to Length(Msg) do
Result := Result + GetChar(Byte(Msg));
DecodeLen := Length(Msg);
end;
esSevenBit: begin
t := EncodeSevenBit(Msg);
for i:=1 to Length(t) do
Result := Result + GetChar(Byte(t));
DecodeLen := Length(t);
end;
end;
end;



说几句不该说的话。

今天好气愤。遇到一个人,说硬要我的核心代码。给他这个解析代码给他,还闲太差。给他一些网址,闲没多少用。我说核心代码不轻易给,除非有补偿。他便骂我是买代码。
反问一句。这年头,程序员是不是就该全部开源。程序员就不要吃饭。程序员研究出来的代码,就该无偿提供出来。
当然,这个人不是楼主,楼主很有礼貌的。

大富翁肯出来解答的牛人,几乎很少了。也不知道是什么缘因。我刚才这里半年,也只是个菜鸟水平,但看到有些人,开口闭口要代码。真的感觉,劳动成果不被重视。程序员被看得先不值钱。
 
不知和更高的8位解码和16为解码有关系吗,那位高人能指教一下,说明一下16为解码的代码,谢谢
 
怎么没有高人指教呀,请各位高人看看菜鸟的问题,帮忙解决一下
 
问题解决了吗
 
我的理解是你的传入参数就没有8,是吗?
 
我这有本书.你要不要看看.
 
linchhero,对你深表同情,
做程序的人什么都免费,那就是天大的SB
微软的东西不免费,可是有多少人是在他的基础之上生存的
UNIX免费,他给了哪些人饭碗?
做程序的人,不要砸了自己的饭碗!
 
不知和更高的8位解码和16为解码有关系吗,那位高人能指教一下,说明一下16为解码的代码,谢谢
 
10.1前的问题,至今没有解决,挺郁闷的,思考了这么常时间也没有太大的眉目。
今天突然想到AT+CMGF=0//是按PDU模式收发,若本人把AT+CMGF=1//按文本形式收发,不知可否,请各位高人指教
 
最近在做一个关于短消息的编程,当用户发一条短信给Gsm modem时,modem根据发的内容,将从数据库中读取相应的内容,然户将相应的内容以一条短信的形式发送给用户。可是当输入短信长度小于<=7时,可以完全读取用户发来的内容,例如&quot;1411103&quot;,它显示1411103,但是当输入的短信长度>7时,不能完全读取用户发来的信息,例如&quot;14111038&quot;,它只显示1411103,后面的8没有读取出来,也就是说短消息只要大约>7的长度,它就不能完全读取。
下面菜鸟将用到的代码列出来,请各位高人帮忙,谢谢!!
 
怎么没有高人给菜鸟解答呢?请各位高人看看,谢谢
 
各位高人都进来看看了,帮菜鸟解决一下这个问题
 
后退
顶部