weitom1982

向各位技术前辈学习,学习再学习.
posts - 299, comments - 79, trackbacks - 0, articles - 0
  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

[编程宝典]C#开发短信的方法和简介
[ 2005-11-27 12:13:00 | By: 自由人 ]
 

C#开发短信的方法和简介

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

Feedback

# re: [编程宝典]C#开发短信的方法和简介   回复  更多评论   

2008-05-07 14:15 by dahai
能不能把CDMA的也给我们讲一下啊!!!

# re: [编程宝典]C#开发短信的方法和简介   回复  更多评论   

2008-12-15 17:03 by Allis
using JustinIO;

JustinIO 这个是?

请教通过短信猫发送短信,收到乱码怎么处理呢?

# re: [编程宝典]C#开发短信的方法和简介   回复  更多评论   

2008-12-16 10:54 by 高山流水
c++里就是一个struct
使用控件和串口类你可以直接生成自己的对象
利用现成的函数

对手机收到的信息,非正常格式(这里可以是短信格式)不做处理,否则按短信格式解析出来.
你这里提到的乱码是不是没有按照格式来解析,因为短信可以有多个格式,上面提到了三种,有时也会遇到扩展格式或非标准格式,但这种情况可能性极小.
另外要说的是我们收发短信的过程中一个重要的步骤是和短信网关(代指,基站和服务商)来打交道,接口是规范的,也就是被定死的,不标准的数据不能通过服务商提供的信道获得处理,这也是为什么我们的手机不会像电脑一样收到一些莫名其妙的数据(当然电脑因为有操作系统看的不明显,底层实际上是不断受到各种网络上的数据的.)
如果还有不清楚的地方,可以把收到的乱码和操作流程图发给我,我看看能不能提供点帮助.

# re: [编程宝典]C#开发短信的方法和简介   回复  更多评论   

2009-11-26 21:48 by 啊啥得分
dd

# re: [编程宝典]C#开发短信的方法和简介   回复  更多评论   

2009-11-26 21:51 by 白影
.我想了解一下具体的信息 你能告诉我么 我的qq是529123958
我用的短信猫在超级终端里好使 可是我不会使用 不知道怎么编写程序使短信猫和程序联系在一起 麻烦你帮助我一下啊!!

# re: [编程宝典]C#开发短信的方法和简介   回复  更多评论   

2009-11-27 15:54 by 白影
你怎不说话呢

# re: [编程宝典]C#开发短信的方法和简介   回复  更多评论   

2009-11-27 15:59 by weitom1982
已经回复你的qq邮箱
只有注册用户登录后才能发表评论。