⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 手机短信息的编程.htm

📁 GPS的资料,上来和大家分享,正做这个的朋友可以看看.
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<P>可以使用 </P>
<P>dt1.Clear();<BR>dt.Dispose();</P>
<P>来释放资源,但是请注意处理可能出现的问题:插入相同的记录!:)</P>
<P>---------------</P>
<P>计算更新时会发生一个问题:计算列并不修改行的状态,所以Update时会"没有要更新的数据行",正等解决</P>
<P>-------------2006年12月21日9时49分-Jace</P>
<P>行状态修正如下:</P>
<P>//此处应该将dt1的行状态进行改变<BR>foreach (DataRow dr in dt1.Rows)<BR>{</P>
<P>if (dr.RowState == DataRowState.Unchanged)<BR>{<BR>dr.SetModified();</P>
<P>}<BR>}</P>
<P>--整个更新方式:</P>
<P>// DataView dv = dt.DefaultView;<BR>//dv.RowStateFilter = 
DataViewRowState.ModifiedCurrent;</P>
<P><BR>DataTable dt1 = dt.Clone();//更新自动处理的数据<BR>//定义主键<BR>DataColumn[] keys = 
new DataColumn[2];<BR>keys[0] = dt1.Columns["工号"];<BR>keys[1] = 
dt1.Columns["年月"];<BR>dt1.PrimaryKey = keys;</P>
<P>for (int i = 0; i &lt; dt1.Columns.Count; 
i++)<BR>{<BR>dt1.Columns[i].Expression = null;<BR>}<BR>dt1.Merge(dt);</P>
<P>//dv.RowStateFilter = 
DataViewRowState.ModifiedCurrent;<BR>//此处应该将dt1的行状态进行改变<BR>foreach (DataRow dr 
in dt1.Rows)<BR>{</P>
<P>if (dr.RowState == 
DataRowState.Unchanged)<BR>{<BR>dr.SetModified();//dr.SetAdded();</P>
<P>}<BR>}</P>
<P>da.Update(dt1);<BR>dt1.Clear();<BR>dt1.Dispose();<BR>dt.AcceptChanges();</P>&nbsp;<A 
href="http://liujace.itpub.net/post/4284/240685">查看全文</A>
<P></P><BR style="CLEAR: both"></DIV>
<DIV class=contentcomments><A class=commentfoot 
href="http://liujace.itpub.net/post/4284/240685#comments">评论 (0)</A> <A 
class=commentfoot href="http://liujace.itpub.net/trackbacks/4284/240685">引用 
(0)</A> <A class=commentfoot 
href="http://liujace.itpub.net/category/4284/10421">手机编程[3]</A> <A 
class=commentfoot href="http://liujace.itpub.net/category/4284/7950">技术资源[7]</A> 
<A class=commentfoot 
href="http://liujace.itpub.net/category/4284/7956">开源项目[1]</A> <A 
class=commentfoot 
href="http://liujace.itpub.net/category/4284/7955">C#编程[11]</A> <A 
class=commentfoot 
href="http://liujace.itpub.net/category/4284/42845">随心记事[0]</A> </DIV></DIV>
<DIV class=post><!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"                                   xmlns:dc="http://purl.org/dc/elements/1.1/"                                   xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"><rdf:Description                             rdf:about="http://liujace.itpub.net/post/4284/36779"                             dc:identifier="http://liujace.itpub.net/post/4284/36779"                             dc:title="C#开发终端式短信的原理和方法(转自 蚕蛹) "                             trackback:ping="http://blog.itpub.net//trackback.php?id=36779"/></rdf:RDF> -->
<DIV class=contenttitle><A 
href="http://liujace.itpub.net/post/4284/36779">C#开发终端式短信的原理和方法(转自 蚕蛹) 
</A></DIV>
<DIV class=contenttime>liujace - by - 30 七月, 2005 09:51</DIV>
<DIV id=blogbody>
<P>
<P><SPAN class=f14><FONT 
size=2>本文介绍了短信的原理和实现方法,重点说明了短信的编码方式、AT指令以及用C#实现串口通讯的方法。</FONT></SPAN></P>
<P><SPAN class=f14><FONT 
size=2><STRONG>简介</STRONG>  没发过短信的年轻人肯定是属于那种受保护的稀有动物,通讯发达的今天短信已经成为人们交流的重要手段,其中也蕴含着巨大的市场和经济利益,掌握短信技术的人才也受到各大公司的追捧是目前职场上耀眼的明星。本文介绍了短信的原理和实现方法,重点说明了短信的编码方式、AT指令以及用C#实现串口通讯的方法。</FONT></SPAN></P>
<P><SPAN class=f14><FONT size=2><STRONG>前言</STRONG>  目前,主有三种发送短信的方式:<BR><BR>  1、 
网关方式:就是向当地的电信部门申请,不需要额外的设备,适用于大型的通信公司,像华为、傲天、中兴、亚信等。<BR><BR>  2、 终端方式:就是借助像GSM 
MODEM之类的设置(支持AT指令的手机也行),通过数据线连接电脑,来发送短信,用这种方法比较适用于小型及个人。要实现这种方式必须理解串口通信、AT指令、短信编码、解码,这也是本文讨论的重点。<BR><BR>  3、 
利用一些网站来实现,方式简单,不过对网站依赖性太高,对网络的要求也比较高,非常不适于进行项目开发</FONT></SPAN></P>
<P><SPAN class=f14><SPAN class=f14><FONT 
size=2><STRONG>原理篇</STRONG>  <B>短信编码</B><BR><BR>  在收发短信方面,按时间产生先后,共产生了三种模式:Block 
Mode、基于AT指令的Text Mode、基于AT指令的PDU Modem, Text 
Mode比较简单,多款诺基亚手机均支持该模式。西门子的手机大多只支持PDU模式,PDU模式是发送或接收手机SMS信息的一种方法,短信息正文经过十六进制编码后被传送。目前,PDU已取代Block 
Mode,因我们主要探讨PDU模式的发送。以西门子3508手机为例。<BR><BR>  SMS是由Etsi所制定的一个规范(GSM 03.40 和 GSM 
03.38)。当使用7-bits编码时,它可以发送最多160个字符;但用8-bit编码,最多可以发送140个字符,通常无法直接通过手机显示;还有用16-bit编码时,最多70个字符,被用来显示Unicode(UCS2)文本信息,可以被大多数的手机所显示。我们今天讨论的是UCS2编码,也就是说,最多只能发送70个字符,不管英文还是中文。<BR><BR>  现例如我们现在要发送如下信息,向我的手机13715342642发送"你好,Hello!"。在没有发送之前,你要清楚,手机SIM卡所在地的短信中心号,并不是你现在所在地方的短信中心号,像我在深圳,深圳的短信中心号是:8613800755000,即使我现在到外地,短信中心号仍是深圳。从上面我们得到了下面的信息:<BR><BR>  接收的手机号:13715342642<BR>  短信中心号:8613800755000<BR>  短信内容:你好,Hello!<BR><BR>  在实际使用中,上面这些信息并不为手机所执行,要进行编码手机才会执行,先不管,看看编码后的信息:<BR><BR>0891683108705500F011000D91683117352446F2000800124F60597DFF0C00480065006<BR>C006C006F0021<BR><BR>  看不懂吧,我来解释一下:<BR><BR>  08 
- 指的是短信中心号的长度,也就是指(91)+( 683108705500F0)的长度<BR><BR>  91 - 
指的是短信息中心号码类型。91是TON/NPI遵守International/E.164标准,指在号码前需加'+'号;此外还有其它数值,但91最常用。<BR><BR>  683108705500F0 
- 
短信息中心号码。由于位置上略有处理,实际号码应为:8613800731500(字母F是指长度减1)。这需要根据不同的地域作相应的修改。前面的(08)+(91)+( 
683108705500F0)实际上就构成了整个短信的一部份,通称短消息中心地址(Address of the SMSC)。<BR><BR>  11 - 
文件头字节<BR><BR>  00 - 信息类型(TP-Message-Reference)<BR><BR>  0D - 被叫号码长度<BR><BR>  91 
- 
被叫号码类型<BR><BR>  其实在实际处理中,我们通常把11000D91写死在程序中,因为在国内,这些数据都是不会改变的。<BR><BR>  683117352446F2 
-被叫号码,经过了位移处理,实际号码为"8613715342642"。上面的(00)+(0D)+(91)+( 
683117352446F2),构成了整个短信的第二部份目的地址(TP-Destination-Address)。<BR><BR>  00 - 
协议标识TP-PID,这里一般为00<BR><BR>  08 - 
数据编码方案TP-DCS(TP-Data-Coding-Scheme),采用前面说的USC2(16bit)数据编码<BR><BR>  00 - 
有效期TP-VP(TP-Valid-Period)<BR><BR>  12-长度TP-UDL(TP-User-Data-Length),也就是4F60597DFF0C00480065006C006C的长度 
36 / 2 = 18 的十六进 12<BR><BR>  4F60597DFF0C00480065006C006C 006F0021- 
这里就是短信内容了,实际内容为:"你好,Hello!"程序实现,请参考本文章所带源程序的PDUdecoding.cs。</FONT></SPAN></SPAN></P>
<P><SPAN class=f14><FONT 
size=2><STRONG>AT指令</STRONG>  说到AT指令可多了,有厚厚的一本书,不属于我们今天讨论的范围,在这里我仅讨论在发送短信中必须要用的几个AT指令。<BR><BR>  与SMS有关的GSM 
AT指令(from GSM07.05)如表1所示:</FONT></SPAN></P>
<P>
<P>
<TABLE cellSpacing=0 width="100%" border=1>
  <TBODY>
  <TR>
    <TD width="11%"><FONT size=2>AT 指令</FONT></TD>
    <TD width="89%"><FONT size=2>功 能 </FONT></TD></TR>
  <TR>
    <TD width="11%"><FONT size=2>AT+CMGC</FONT></TD>
    <TD width="89%"><FONT size=2>Send an SMS command(发出一条短消息命令)</FONT></TD></TR>
  <TR>
    <TD width="11%"><FONT size=2>AT+CMGD</FONT></TD>
    <TD width="89%"><FONT size=2>Delete SMS message(删除SIM卡内存的短消息) 
</FONT></TD></TR>
  <TR>
    <TD width="11%"><FONT size=2>AT+CMGF</FONT></TD>
    <TD width="89%"><FONT size=2>Select SMS message 
      formate(选择短消息信息格式:0-PDU;1-文本)</FONT></TD></TR>
  <TR>
    <TD width="11%"><FONT size=2>AT+CMGL</FONT></TD>
    <TD width="89%"><FONT size=2>List SMS message from preferred 
      store(列出SIM卡中的短消息PDU/text: 0/"REC UNREAD"-未读,1/"REC READ"-已读,2/"STO 
      UNSENT"-待发,3/"STO SENT"-已发,4/"ALL"-全部的)</FONT></TD></TR>
  <TR>
    <TD width="11%"><FONT size=2>AT+CMGR</FONT></TD>
    <TD width="89%"><FONT size=2>Read SMS message(读短消息)</FONT></TD></TR>
  <TR>
    <TD width="11%"><FONT size=2>AT+CMGS</FONT></TD>
    <TD width="89%"><FONT size=2>Send SMS message(发送短消息) </FONT></TD></TR>
  <TR>
    <TD width="11%"><FONT size=2>AT+CMGW</FONT></TD>
    <TD width="89%"><FONT size=2>Write SMS message to 
      memory(向SIM内存中写入待发的短消息)</FONT></TD></TR>
  <TR>
    <TD width="11%"><FONT size=2>AT+CMSS</FONT></TD>
    <TD width="89%"><FONT size=2>Send SMS message from storage(从SIN|M内存中发送短消息) 
      </FONT></TD></TR>
  <TR>
    <TD width="11%"><FONT size=2>AT+CNMI</FONT></TD>
    <TD width="89%"><FONT size=2>New SMS message 
    indications(显示新收到的短消息)</FONT></TD></TR>
  <TR>
    <TD width="11%"><FONT size=2>AT+CPMS</FONT></TD>
    <TD width="89%"><FONT size=2>Preferred SMS message 
    storage(选择短消息内存)</FONT></TD></TR>
  <TR>
    <TD width="11%"><FONT size=2>AT+CSCA </FONT></TD>
    <TD width="89%"><FONT size=2>SMS service center 
  address(短消息中心地址)</FONT></TD></TR>
  <TR>
    <TD width="11%"><FONT size=2>AT+CSCB</FONT></TD>
    <TD width="89%"><FONT size=2>Select cell broadcast messages(选择蜂窝广播消息) 
      </FONT></TD></TR>
  <TR>
    <TD width="11%"><FONT size=2>AT+CSMP</FONT></TD>
    <TD width="89%"><FONT size=2>Set SMS text mode parameters(设置短消息文本模式参数) 
      </FONT></TD></TR>
  <TR>
    <TD width="11%"><FONT size=2>AT+CSMS</FONT></TD>
    <TD width="89%"><FONT size=2>Select Message 
  Service(选择短消息服务)</FONT></TD></TR></TBODY></TABLE></P>
<P><FONT size=2>表一:相关的GSM 
AT指令<BR><BR>  我现在以实例来说明这些指令的使用方法:<BR><BR>  先用手机数据线将手机连接到电脑串口,并将串口的波特率设置为19200,可以开始了。<BR><BR>  1、首先测试你的连接及手机是否支持AT指令,请在你的串口调试程序中输入:<BR><BR>  AT<回车><BR><BR>  屏幕上返回"OK"表明计算机与手机连接正常,那样我们就可以进行其它的AT指令测试了<BR><BR>  2、设置短信发送格式<BR><BR>  AT+CMGF=1<回车><BR><BR>  屏幕上返回"OK"表明现在短信的发送方式为PDU方式,如果是设置为TEXT方式,则,AT+CMGF=0<回车><BR><BR>  3、 
发送短信<BR><BR>  发送内容及手要号仍旧同上面在编码中的一样,编码后,得到要发送的数据如下<BR><BR>0891683108705505F011000D91683117352446F2000800124F60597D002C00480065006<BR>C006C006F0021<BR><BR>  我们用如下指令来发送<BR><BR>  AT+CMGS=33<回车><BR><BR>  如果返回">",就把上面编码数据输入,并以CTRL+Z结尾,稍等一下,你就可以看到返回OK啦。<BR><BR>  说明一下,为什么AT+CMGS=33呢,是这样得来的:<BR><BR>11000D91683117352446F2000800124F60597D002C00480065006C006C006F0021<BR><BR>  这一段字符串的长度除以2得到的结果,上面的字符串,短信中心号加上短信内容得到的,怎么得到的,请回顾一下解码部份<BR><BR>  在我们前面的讨论中,一条完整的短信发送,只要执行三条AT指令,AT、AT+CMGS=?、AT+CMGS=?就可以了。由于篇幅,我只能在这里提到这么多,大家要是想了解更多,可以向各手机厂商索取AT指令白皮书,里面很详细的。<BR><BR>  上面讲到的,只能为我们实际中作准备,我们还必须要一个发送途径,根据我们的需要,我们选择投资最少,实现比较方便的串口通信。注意,串口通过数据线跟手机相连,用AT指令来实现发送短信,在我们选择数据线时,建议购买原厂所配,非原厂所配,在使用过程中,经常出现一些莫明其妙的问题,比如,手机屏幕黑了,手机老是提示电池电量不足之类的。</FONT></P>
<P><FONT 
size=2><STRONG>串口通信</STRONG>  在C#中要实现串口通信,很多人都不知所措,在论坛上经常可以看到"怎么用MSCOMM实现串口通信"、"怎样能过串口与设备相连"诸如此类的问题。其实国外的网友早就把这些列入FAQ中了。<BR><BR>  通常,在C#中实现串口通信,我们有四种方法:<BR><BR>  第一:通过MSCOMM控件这是最简单的,最方便的方法。可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册,不在本文讨论范围。可以访问http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=320 
,一个国外网友的写的教程,作者很热心,我曾有发邮件给他,很快就回复了。<BR><BR>  第二:微软在.NET新推出了一个串口控件,基于.NET的P/Invoke调用方法实现,详细的大家可以访问微软网站http://msdn.microsoft.com/msdnmag/issues/02/10/NETSerialComm/default.aspx,方便得到更多资料。<BR><BR>  第三:就是用第三方控件啦,可一般都要付费的,不太合实际,不作考虑<BR><BR>  第四:自己用API写串口通信,这样难度高点,但对于我们来说,可以方便实现自己想要的各种功能<BR><BR>  在本文,我们采用第四种方法来实现串口通信,不过不是自己写,用一个国外网友现成的已经封装好的类库,不过功能简单点,相对我们来说已经够用了。<BR><BR>  在整个终端短信的操作过程中,与串口的通信,只用到了四个功能,打开、写、读、关闭串口。下面是类库对这四个功能的定义:<BR><BR>  打开串口:<BR><BR>  函数原型:public 
void Open()<BR><BR>  说明:打开事先设置好的端口<BR><BR>  示例:</FONT>
<TABLE width="100%" bgColor=#ffffff>
  <TBODY>
  <TR>
    <TD><FONT size=2>using JustinIO;<BR><BR>static JustinIO.CommPort ss_port = 
      new JustinIO.CommPort();<BR>ss_port.PortNum = COM1; 
      //端口号<BR>ss_port.BaudRate = 19200; //串口通信波特率<BR>ss_port.ByteSize = 8; 
      //数据位<BR>ss_port.Parity = 0; //奇偶校验<BR>ss_port.StopBits = 
      1;//停止位<BR>ss_port.ReadTimeout = 1000; //读超时<BR>try<BR>{<BR> if 
      (ss_port.Opened)<BR> {<BR>  ss_port.Close();<BR>  ss_port.Open(); 
      //打开串口<BR> }<BR> else<BR> {<BR>  ss_port.Open();//打开串口<BR> }<BR> return 
      true;<BR>}<BR>catch(Exception e) <BR>{<BR> MessageBox.Show("错误:" + 
      e.Message);<BR> return false;<BR>}</FONT></TD></TR></TBODY></TABLE><BR><FONT 
size=2>  写串口:<BR><BR>  函数原型:public void Write(byte[] 
WriteBytes)<BR><BR>  WriteBytes 
就是你的写入的字节,注意,字符串要转换成字节数组才能进行通信<BR><BR>  示例:<BR><BR>ss_port.Write(Encoding.ASCII.GetBytes("AT+CGMIr")); 
//获取手机品牌<BR><BR>  读串口:<BR><BR>  函数原型:public byte[] Read(int 
NumBytes)<BR><BR>  NumBytes 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -