SMS Client-Server (短信服务客户机与服务器的实现)

转自:http://blog.csdn.net/chxljtt/archive/2007/11/23/1898753.aspx

者: Ranjan.D.
翻译: [yn]Yuxiang

SMS Client - Server 软件用于发送、读取和删除信息。 它使用 GSM modem 发送 SMS。它监听收到的增量信息,进行信息读取处理,并采取相应的动作。此 SMS 软件需要 GSMComm 类库的支持——你可以下载得到。

C# (C# 1.0)
Windows, .NET (.NET 1.1)
Win32, VS (VS.NET2003), WinForms
Dev
Posted: 10 Sep 2007

下载源代码 (http://www.codeproject.com/useritems/SMS/SMS.zip - 534.2 KB)
原文地址:SMS Client - Server

image

简介
SMS Client - Server 是用于发送和接收信息(SMS)的应用软件。它监听收到的增量信息,以有效的格式则进行信息处理。注意,处理到达的信息,依赖于在本文后面谈到的应用程序。


我准备对下列内容进行解释:
1) 通信端口配置
2) 接收增量信息
3) 发送信息
4) 读取全部信息 (用户发送的信息)
5) 删除信息(一条或全部)

我使用了 GSMComm 类库来发送和接收 SMS。你需要有 GSM modem 或电话来发送 SMS。

代码使用
1) 通信端口配置:
image

CommSettings 类用于保存 comm 端口配置。

public class CommSetting
{
public static int Comm_Port=0;
public static Int64 Comm_BaudRate=0;
public static Int64 Comm_TimeOut=0;
public static GsmCommMain comm;

public CommSetting()
{
//
// 在此处添加构造函数逻辑
//
}
}



Comm 是一个GsmCommMain 类型对象,用于发送和接收信息。我们必须为 GsmCommMain 类型的 comm 对象配置 COM 端口、波特率和超时设置。然后尝试打开上述配置。在选定 Comm 端口、波特率和超时设置后,我们可以单击[Test] 按钮测试 Comm 端口配置。经过一段时间后,如果 comm 端口不能被打开,软件将给出提示信息“ No phone connected(未连接到电话)” ,这大体上是因为波特率配置不当。改变波特率后,再次单击[Test] 按钮测试,直到出现提示信息“Successfully connected to the phone.(连接电话成功)”。

在使用配置创建一个 GSMComm 对象之前,我们需要验证端口号、波特率和超时设置。

EnterNewSettings() 执行验证,如果验证通过,返回 true,并调用 SetData(port,baud,timeout) 设置 comm 配置数据。

下面是尝试连接的代码段,如果产生问题,将出现“Phone not connected” 提示信息,你可以单击[retry] 按钮重试,或者取消连接尝试。


image

2) 接收增量信息
我们将为 GSMComm 对象 comm 添加下列事件。
a)PhoneConnected 电话连接事件:
    当你尝试打开 Comm 端口时,引发此事件。电话连接事件的句柄是 comm_PhoneConnected,在 ConnectedHandler 委托的协作下,它调用方法 OnPhoneConnectionChange(bool connected) 。


b) MessageReceived 收到信息事件:

    当信息到达 GSM 电话时,此事件被引发。我们以 MessageReceivedEventHandler 注册事件。当增量信息到达时,comm_MessageReceived 方法将被调用,它轮番调用 MessageReceived() 方法处理未读信息。 GSMComm 对象 comm 有一个用于读取信息的 ReadMessages 方法,它接收下列电话状态参数 (All, ReceivedRead, ReceivedUnread, StoredSent, 和 StoredUnsent) ,并保存到 SIM 存储器或电话存储器中。

private void MessageReceived()
{
Cursor.Current = Cursors.WaitCursor;
string storage = GetMessageStorage();
DecodedShortMessage[] messages = CommSetting.comm.ReadMessages
(PhoneMessageStatus.ReceivedUnread, storage); 
foreach(DecodedShortMessage message in messages)
{
Output(string.Format("Message status = {0}, Location = {1}/{2}",
StatusToString(message.Status),
message.Storage, message.Index));
ShowMessage(message.Data);
Output("");
}

Output(string.Format("{0,9} messages read.", messages.Length.ToString()));
Output("");
}



上述代码将从 SIM 存储器读取未读信息。 ShowMessage 方法用于显示已读信息。这些信息可以是状态报告、已发送/未发送存储信息,以及已收到信息。

3) 发送信息:
image

你可以在输入目标电话号码和文本信息后,发送 SMS。

如果你想以本机语言 (Unicode) 发送信息,你需要登记 Unicode(UCS2) 发送。GSMComm 对象 comm 的 SendMessage 方法可用于发送 SMS 到任何电话。创建一个 PDU 来发送信息。我们可以直接创建 PDU,例如使用下列代码:

Code:
SmsSubmitPdu pdu = new SmsSubmitPdu(txt_message.Text,txt_destination_numbers.Text,"");



当你以 Unicode 发送信息时,将使用 Pdu 的一个扩展版本。

try
{
// 发送一条 SMS 信息
SmsSubmitPdu pdu;
bool alert = chkAlert.Checked;
bool unicode = chkUnicode.Checked;
if (!alert && !unicode)
{
// straightforward 版
pdu = new SmsSubmitPdu(txt_message.Text, txt_destination_numbers.Text,"");
}
else
{
// 使用 dcs 的扩展版
byte dcs;
if (!alert && unicode)
dcs = DataCodingScheme.NoClass_16Bit;
else if (alert && !unicode)
dcs = DataCodingScheme.Class0_7Bit;
else if (alert && unicode)
dcs = DataCodingScheme.Class0_16Bit;
else
dcs = DataCodingScheme.NoClass_7Bit; pdu = new SmsSubmitPdu(txt_message.Text, txt_destination_numbers.Text, "", dcs);
}

// 如果在此处设置,多次发送同样的信息
int times = chkMultipleTimes.Checked ? int.Parse(txtSendTimes.Text) : 1;
// 发送指定次数的信息
for (int i=0;i"Message {0} of {1} sent.", i+1, times);
Output("");
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}

Cursor.Current = Cursors.Default;




4) 读取全部信息
image

你可以从电话的 SIM 存储器读取全部信息。只需单击[Read All messages]按钮。信息内容(如发送人、时间、文本信息)将被显示在 Data Grid 中。为每条读到的信息创建一行,添加到 Data table 中,把 Data table 写入其数据源。

private void BindGrid(SmsPdu pdu)
{
DataRow dr=dt.NewRow();
SmsDeliverPdu data = (SmsDeliverPdu)pdu;

dr[0]=data.OriginatingAddress.ToString();
dr[1]=data.SCTimestamp.ToString();
dr[2]=data.UserDataText;
dt.Rows.Add(dr);

dataGrid1.DataSource=dt;
}

上述代码将从 SIM 存储器中读取全部未读信息。 ShowMessage 方法用于显示已读信息。这些信息可以是状态报告、已发送/未发送存储信息和已收到信息。在处理收到的信息和已读信息时,只需要改变第一个参数。

处理收到信息:

Code:
DecodedShortMessage[] messages = CommSetting.comm.ReadMessages(PhoneMessageStatus.ReceivedUnread, storage);



读取全部信息:

Code:
DecodedShortMessage[] messages = CommSetting.comm.ReadMessages(PhoneMessageStatus.All, storage);



5) 删除信息(一条或全部)
image

用户发送的全部信息将被存储在 SIM 存储器中,我们将把它显示在 Data grid 中。我们可以通过指定信息的索引号,来删除单条信息。基于索引删除,单击[Delete All]按钮可以从 SIM 存储器中删除全部信息。每条信息将以唯一的索引保存在存储器中。

下面是基于索引删除信息的代码:

Code:
// 以指定的索引,从存储器中删除信息
CommSetting.comm.DeleteMessage(index, storage);



从(SIM/ 电话)存储器中删除全部信息:

Code:
// 从电话存储器中删除全部信息
CommSetting.comm.DeleteMessages(DeleteScope.All, storage);



DeleteScope 枚举包含:
1) All
2) Read
3) ReadAndSent
4) ReadSentAndUnsent

相关应用程序:  (译者注:抱歉,我实在不知道如何使本节的翻译效果更好一些,请参考原文)

修改此软件,你可以实现某些有趣的应用程序:

1) 预付电费系统:

Senario (Customer)

客户将使用充值票证(Coupon)预付电费。充值票证可在商店购买到。客户首先从商店购买充值票证;每张充值票证包含以涂层覆盖的 PIN 码,客户需要刮开涂层查看 PIN 码,然后以指定的信息格式发送一条 SMS 到 SMS 服务器进行充值。 充值的信息格式:RECHARGE <充值票证号码> <客户 ID>


Senario (Server Database)

在服务器上,数据库由客户信息(连同他的电话号码) 组成;需要使用一个名为 Amount 的字段,当客户充值时进行余额更新。这个应用程序变得有些复杂,需要集成一套自动化的仪表读取硬件与软件。自动化仪表读取系统将读取所有仪表数据,并为 客户 计算扣除费用后的余额。

2) 占星术软件:

你可以实现一个占星术软件。用户以他的 zodiac sign 来发送 SMS。SMS 服务器维护一个占星术数据库,数据库中包含 zodiac sign ,以及指定日期占星信息的文本说明。数据需要日常更新,以保存全部的 zodiac signs。用户要取得某天的信息,可使用信息格式“Zodiac Zign”。

3) 远程控制系统:


我们可以实现一个远程控制系统,例如你需要:
1)关闭系统
2)重启系统
3)中止与主机[服务器]的连接

你可以发送一条 SMS,SMS 服务器将监听并处理信息。通过用户发送的特定信息格式,我们可以作出相应的动作。例如,如果以信息格式“SHUTDOWN”发送到 SMS 电话号码,则关闭系统。

结束语:
感谢 GSMComm 类库开发者"Stefan Mayr",否则此项目或许不能完成。
我以该类库来量身定制此应用程序,你可以从下面的“参考资料”中给出的网页链接,来下载示例项目和类库。

参考资料:
http://www.scampers.org/steve/sms/index.htm

posted @ 2009-04-07 16:01  scgw  阅读(1085)  评论(0编辑  收藏  举报