摘 要: 介绍了SerialPort类常用的属性和方法,对操作无线通信模块M1206的主要AT命令格式及功能进行了描述,针对短信传输采用的PDU数据格式单元及编码方式进行了阐述,重点论述了在C#语言中,使用SerialPort类发送短信的程序设计思想和实现方法。在网络应用程序开发中,使用短信收发功能完成信息发布,具有极高的应用价值。
关键词:SerialPort类;串口通信;无线通信模块;短信
基于GSM短信业务已经渗透于生活的各个领域,为每个人所熟知和使用。本文介绍了使用.NET中提供的SerialPort类的属性和方法驱动无线通信模块,使用AT命令实现短信收发。在学生学分预警网络软件开发中,设计学分预警短信发送功能,当学生每学期的学分集低于教学计划规定学分时,程序立即启动短信发送功能,提醒学生注意修订后续的学习计划,避免影响学生如期毕业,达到了预期的目的。
1 SerialPort类介绍
基于无线通信模块的短信收发的核心技术是实现串口通信。.NET Framework4.0类库中System.IO.Ports命名空间,包含了控制串口通信的SerialPort类,该类提供了同步I/O和事件驱动I/O、对中断状态的访问以及对串口驱动程序属性的访问,使用该类可方便地实现所需要串口通信的多种功能[1]。
1.1 SerialPort类常用的属性
SerialPort类提供串行通信端口号,波特率、数据位、停止位、校验位等属性的设置,其中:
PortName:设置通信端口,如COM1、COM2等。
BaudRate:设置通信格式中的波特率(即串口通信的速率),因进行串口通信的双方其波特率需要相同。如果用PC机连接其他非PC系统,波特率则决定于非PC系统。本软件使用无线通信模块的波特率是2 400 b/s。
Parity:设置奇偶校验位,其数据结构为枚举类型。枚举元素为:Odd、Even、Mark、None、Space。
DataBits:数据位长度,取值为5、7、8。
StopBits:停止位,其数据结构为枚举类型。枚举元素为:None、One、OnePointFive、Two。
对于两个进行串行通信的端口,这些参数必须匹配。
1.2 SerialPort类的常用方法
1.2.1 串口的打开和关闭
SerialPort类提供Open()和Close()方法来实现串口的打开或关闭。
1.2.2 数据的发送和接收
SerialPort类提供Write()和WriteLine()方法发送数据,其中:Write()方法用于发送字节数组、字符数据或字符。WriteLine()方法可发送字符串,当发送完数据后,会将换行符作为数据也发送给对方。
SerialPort类提供Read()和ReadLine()方法接收数据,其中:Read()方法接收数据时,需要定义一个字节或数组变量来保存读取的数据,结果返回实际读取的字节或字符数。ReadLine()方法接收数据时,读取数据直至遇到一个换行符,然后返回一个字符串代表一行信息接收完成。
2 SerialPort类的应用
2.1无线通信模块
WaveCom公司推出的GSM/GPRS的无线通信模块M1206,它支持GSM07.05短信协议和GSM07.07接口协议标准,支持移动、联通以及小灵通用户收发短信,适用于各行各业各个领域作为无线数据通信、短信息通告和短信查询等应用。
2.1.1 操作无线通信模块M1206的主要AT命令集及功能描述
无线通信模块与计算机之间的通信协议是一些AT指令集,每个指令以AT+开头,以回车结尾。每个命令执行成功与否都有相应的返回[2]。在短信收发软件中常用的AT指令如下:
ATE0:检测无线通信模块M1206,关闭命令回显。返回OK,说明GSM工作正常。
AT+CMGF=0:设置发送和接收短消息方式命令。当值为“0”时为PDU模式,短信息正文经过USC2编码转换为16 bit的Unicode码后被传送,最多70个字符;当值为“1”时为TEXT模式,此时只可传送140个字符,由于短信息的内容均为8 bit表示的ASCII码,实现方法比PDU方式简单。
AT+CMGS=<PDU的十进制长度>:发送短消息命令,模块M1206收到此命令后,若响应正常,则返回“>”提示符,这时便可发送数据信息,并以Ctrl/Z(ASCII=0x1A)结束。
AT+CSMP=<fo>,<vp>,<pid>,<dcs>:用于设置文本模式参数,其中:<fo>设置使用短信提交,<vp>设置短信息的有效周期,<pid>为协议标识符,<dcs>设置短信息的编码方案。
AT+CNMI=1,1,0,0,1:设置新消息指示方式命令。此命令使M1206收到短信时返回的命令为"+CMTI: "SM",短信息索引号"。
AT+CMGR=<index>:接收短消息命令,index为最新收到的短信息索引号。
发送短信息时使用的控制符:结束符(<CR>)十六进制的0x0D;发送符(<Ctrl/Z>)十六进制的0x1A。
2.1.2 无线通信模块的硬件连接
PC机通过RS232串口与无线通信模块M1206连接,将SIM卡插入无线通信模块的插卡槽,最后接通无线通信模块外接电源。观察指示灯,若指示灯开始闪烁,证明无线通信模块连接正确,可以使用;若指示灯不亮,则需要检查无线通信模块的连接是否正确,或者无线通信模块是否完好。
2.2 短信传输数据单元格式的解析及编码
短信发送的常用编码格式有两种:Text模式和PDU(Protocol Description Unit)模式。Text模式收发短信代码简单,实现起来比较容易,但不支持中文短信;PDU 模式既支持英文,又支持中文。目前,PDU模式应用最为广泛,中国移动和中国联通都提供支持PDU模式的短消息业务。PDU模式收发短信可以使用3种编码:7 bit、8 bit和UCS2编码。7 bit编码用于发送普通的ASCII字符,8 bit编码通常用于发送数据消息,UCS2编码用于发送Unicode字符。本文收发短信软件采用PDU模式的UCS2编码方式。
2.2.1 PDU数据单元格式解析
PDU数据单元不仅包含可传输的消息本身,还包括其他很多信息。如:SMS服务中心号码、目标号码、回复号码、编码方式和服务时间等[3]。PDU数据包格式有:SCA、PDU-type、MR、DA、PID、DCS、VP、UDL、UD。分别描述如下:
SCA(Service Center Address)短消息服务中心地址,包含三个部分:①Length是服务中心地址长度,取值为00时,表示使用SIM卡上设置的短信中心号码。②Type是短信中心地址的类型,取值为81时为国内号码;取值为91时为国际号码。③服务中心地址。
PDU-type:设置PDU类型。取值为51时,代表有报头短信;取值为11时,代表普通短信。
MR:是消息参考。在实际应用时,用于设置目的地址号码长度。值为0x0D时,表示目的地址号码长度为13。 DA:目的地址。取值为91时,表示目标号码是国际号码(带+号);如果为81时,则表示是本地号码。
PID:协议标识。值为00时,表示普通GSM类型,点到点方式。
DCS:数据编码方案。用于设置短消息内容的编码方式。取值为08时,是UCS2编码,用于汉字;取值为00时,用于英文字符;取值为04时,用于图片等数据。
VP:短信有效期。取值为00时,表示短信有效期为5 min。
UDL:用户数据长度。使用UCS2编码方式时,则表示后面用户数据段的长度(即UD的字节数)。
UD:用户数据,即传输数据内容Unicode编码。
2.2.2 发送消息内容的编码方式
发送的消息内容要进行正确的编码才可以发送到串口,否则接收到的将会是乱码。其编码遵循USC2编码的规则进行编码,即将每个字符(1~2 B)转换为16 bit的Unicode码。
信息中心发送SIM卡号码,接收方SIM卡号码的编码方式是:将每两位数据位置互换,余下最后单个位的补F。
编码后的消息组成=089168+发送SIM卡地址编码+11000D9168+接收手机号码编码+000800+短信息内容编码后的字节数+短信息内容编码+Ctrl/Z。其中,“+”为字符串连接符,不发送。
2.3 短信发送程序的设计思想与实现方法
在使用SerialPort类进行串口通信时,一般的程序流程是设置串行通信端口号、波特率、数据位数、停止位和校验位,再打开串口连接,发送数据,最后关闭串口连接。C#语言中调用SerialPort类时首先要添加引用语句:using System.IO.Ports[4],定义SerialPort类实例,并直接初始化,设置串行通信端口以及波特率(与无线通信模块波特率一致)等参数。
发送消息内容编码的实现通过.NET Framework提供的Encoding类实现Unicode编码。在C#中调用此类需引用名称空间System.Text;使用for语句完成发送和接收SIM卡号码的编码转换。
使用SerialPort类的Write()方法发送AT指令及PDU数据包,即完成短信的发送。
关键程序代码如下:
/*端口初始化*/
SerialPort my_send=new SerialPort("com1",2400,Parity.None, 8,StopBits.One);
string Send_No="13800532112";
string RecieveNo=13005321618;
string Note="同学你好!学分集欠缺!";
string message="089168";
/*发送地址编码*/
char[]Pdumcenter=(Send_No+"F").ToCharArray();
for (int i=0;i<Pdumcenter.Length;i+=2)
{
message+=Pdumcenter[i+1].ToString();
message+=Pdumcenter[i].ToString();
}
message+="11000D9168";
/*接收目的地址编码*/
char[]PduRecieveNo=(RecieveNo+"F").ToCharArray();
for (int i=0;i<RecieveNo.Length;i+=2)
{
message+=PduRecieveNo[i + 1].ToString();
message+=PduRecieveNo[i].ToString();
}
message+="000800";
/*消息内容编码*/
byte[] Unote=Encoding.Unicode.GetBytes(note);
message+=Unote.Length.ToString("X2");
for (int i=0;i<Unote.Length; i+=2)
{
message+=Unote[i+1].ToString("X2");
message+=Unote[i].ToString("X2");
}
int PduLength=(message.Length-18)/2;
/*发送信息*/
Try
{
my_send.Open();
my_send.Write("AT+CMGF=0\r");
my_send.Write("AT+CSMP=17,167,0,240\r");
my_send.Write("AT+CMGS="+PduLength+ "\r");
my_send.Write(message);
my_send.Write(Encoding.ASCII.GetBytes("\x1A"),0,
Encoding.ASCII.GetBytes("\x1A").Length);
my_send.Close();
}
catch
{Response.Write("发送失败!");}
在VS.NET2010平台上使用C#语言开发网络应用软件,引用SerialPort类,实现与无线通信模块WaveCom M1206通信;使用AT命令发送、接收短信。在网络应用程序开发中,使用SerialPort类实现短信收发功能,完成信息发布有极高的应用价值,如在健身房会员管理软件中设计会员短信通知功能,将健身房的优惠信息、会员卡有效期预警等信息,通过短信随时发送给各位会员,使会员能够合理安排健身计划。本文方法在实际应用中取得了很好的效果。
参考文献
[1] WEIMENG L.C#与VB .NET网络通信开发实战[M].田国法,吴兰陟,译.北京:人民邮电出版社,2008.
[2] GSM 07.07:Digital cellular telecommunications system (Phase 2+); AT command set for GSM mobile equipment 2004.
[3] 王国军.GSM长短信PDU编码分析[J].电脑与信息技术2011,19(2):48-50.
[4] 邹建峰.ASP.NET动态网站设计教程[M].北京:清华大学出版社,2011.