如今手機已成為福士交流的主要工具。有關手機的程式開發越來越廣泛,本節通過典型執行個體介紹如何利用簡訊貓發送、接收簡訊。
1.方案分析
發簡訊的一種方法是利用簡訊貓發簡訊,本例中使用的是生產的串口簡訊貓。
所謂簡訊貓,其實是一種工業級GSM MODEM,通過串口與電腦串連,可以通過AT指令控制進行簡訊收發的裝置。國內目前應用較多的簡訊貓,都是以SIEMENS或WAVECOM模組為核心組裝而成的,與普通手機相比更為穩定高效。
簡訊貓是利用SIM卡傳送簡訊的硬體裝置,通過串口或USB介面(根據裝置型號而定)與電腦相連。在程式中可以利用簡訊貓發送或接收簡訊。本例使用的是的串口簡訊貓。在購買簡訊貓時會附帶有SDK的簡訊貓開發包,其中提供了操作簡訊貓的函數(封裝在dllforvc.dll動態庫中)。
2.實施過程
下面利用簡訊貓傳送簡訊,單擊【傳送簡訊】按鈕就可以完成對指定手機號碼的簡訊發送,當有新的簡訊發送過來的時候,單擊【接收簡訊】按鈕就可以將簡訊顯示出來。
程式實現具體步驟:
(1)建立一個網站,預設首頁為Default.aspx。
(2)在頁面中添加6個TextBox文字框,分別用於顯示簡訊貓的COM連接埠、傳輸速率、機器號碼、簡訊貓的授權號碼、輸入接收簡訊的手機號碼和要發送的簡訊內容。
(3)在頁面中添加2個Button按鈕,分別用於傳送簡訊和接收簡訊。
(4)程式主要代碼如下。
首先建立一個類庫,將其命名為Baisc,然後在此類庫中建立一個名為GMS的公用類,用於擷取簡訊貓附帶的動態庫dllforvc.dll中的一些函數,之後將此類庫編譯成Basic.dll檔案,在項目中將其引用,具體代碼如下。
匯入必要的命名空間,代碼如下。
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
通過調用dllforvc.dll中的一些函數,擷取其中的各種方法供Default.aspx頁面中調用,具體的代碼如下。
namespace Basic
{
public class GMS
{
//初始化gsm modem,並串連gsm modem
//參數說明:
//device:標識通訊連接埠,如果為NULL,系統會自動檢測。
//baudrate:標識通訊傳輸速率,如果為NULL,系統自動檢測。
//initstring:標識初始化命令,為NULL即可。
//charset:標識通訊字元集,為NULL即可。
//swHandshake:標識是否進行軟體握手,為FALSE即可。
//sn:標識簡訊貓的授權號,需要根據實際情況填寫。
[DllImport("dllforvc.dll",
EntryPoint = "GSMModemInitNew",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
public static extern bool GSMModemInitNew(
string device,
string baudrate,
string initstring,
string charset,
bool swHandshake,
string sn);
//擷取簡訊貓新的標識號碼
//參數說明:
//device :通訊連接埠,為null時系統會自動檢測。
//baudrate :通訊傳輸速率,為null時系統會自動檢測。
[DllImport("dllforvc.dll",
EntryPoint = "GSMModemGetSnInfoNew",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
public static extern string GSMModemGetSnInfoNew(string device, string baudrate);
//擷取當前通訊連接埠
[DllImport("dllforvc.dll",
EntryPoint = "GSMModemGetDevice",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
public static extern string GSMModemGetDevice();
//擷取當前通訊傳輸速率
[DllImport("dllforvc.dll",
EntryPoint = "GSMModemGetBaudrate",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
public static extern string GSMModemGetBaudrate();
//中斷連線並釋放記憶體空間
[DllImport("dllforvc.dll",
EntryPoint = "GSMModemRelease",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
public static extern void GSMModemRelease();
//取得錯誤資訊
[DllImport("dllforvc.dll",
EntryPoint = "GSMModemGetErrorMsg",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
public static extern string GSMModemGetErrorMsg();
//傳送簡訊息
//參數說明:
//serviceCenterAddress:標識簡訊中心號碼,為NULL即可。
//encodeval:標識簡訊息編碼格式,如果為8,表示中文簡訊編碼。
//text:標識簡訊內容。
//textlen:標識簡訊內容的長度。
//phonenumber:標識接收簡訊的電話號碼。
//requestStatusReport:標識狀態報表。
[DllImport("dllforvc.dll",
EntryPoint = "GSMModemSMSsend",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
public static extern bool GSMModemSMSsend(
string serviceCenterAddress,
int encodeval,
string text,
int textlen,
string phonenumber,
bool requestStatusReport);
//接收簡訊息返回字串格式為:手機號碼|簡訊內容||手機號碼|簡訊內容||
//RD_opt為1接收簡訊息後不做任何處理,0為接收後刪除資訊
[DllImport("dllforvc.dll",
EntryPoint = "GSMModemSMSReadAll",
CharSet = CharSet.Ansi,
CallingConvention = CallingConvention.StdCall)]
public static extern string GSMModemSMSReadAll(int RD_opt);
}
}
在Default.aspx頁中,匯入命名空間using System.Text,具體代碼如下。
using System.Text;
當頁面載入時,通過調用GMS 類中的GSMModemGetSnInfoNew方法、GSMModemGetDevice方法和GSMModemGetBaudrate方法分別用於顯示機器號碼、COM連接埠和傳輸速率,具體代碼如下。
protected void Page_Load(object sender, EventArgs e)
{
//機器號碼
this.txtJQHM.Text = Basic.GMS.GSMModemGetSnInfoNew(txtCOM.Text, txtBTL.Text);
this.txtCOM.Text = Basic.GMS.GSMModemGetDevice(); //COM1
this.txtBTL.Text = Basic.GMS.GSMModemGetBaudrate(); //傳輸速率
}
當各項資訊填寫完畢之後,單擊【傳送簡訊】按鈕,程式首先通過GMS類中的GSMModemInitNew方法串連裝置,如果串連成功,程式會通過GMS類中的GSMModemSMSsend方法將輸入的簡訊內容發送到指定的手機號碼中,如果串連失敗,程式會通過GMS類中的GSMModemGetErrorMsg方法輸出錯誤資訊,【傳送簡訊】按鈕的 Click事件中的代碼如下。
protected void btnSend_Click(object sender, EventArgs e)
{
if (txtSJHM.Text == "")
{
Page.RegisterStartupScript("","<script>alert('手機號碼不可為空!')</script>");
txtSJHM.Focus();
return;
}
if (txtContent.Text == "")
{
Page.RegisterStartupScript("", "<script>alert('簡訊內容不可為空!')</script>");
txtContent.Focus();
return;
}
//串連裝置
if (Basic.GMS.GSMModemInitNew(txtCOM.Text, txtBTL.Text, null, null, false, txtPower.Text) == false)
{
Page.RegisterStartupScript("","<script>alert('裝置串連失敗!'" + Basic.GMS.GSMModemGetErrorMsg()+"')</script>");
return;
}
// 傳送簡訊
if (Basic.GMS.GSMModemSMSsend(null, 8, txtContent.Text, Encoding.Default.GetByteCount(txtContent.Text), txtSJHM.Text, false) == true)
Page.RegisterStartupScript("","<script>alert('簡訊發送成功!')</script>");
else
Page.RegisterStartupScript("","<script>alert('簡訊發送失敗!'" + Basic.GMS.GSMModemGetErrorMsg()+"')</script>");
}
當單擊【接收簡訊】按鈕時,程式通過GSM類中的GSMModemSMSReadAll方法將發送到手機卡中的簡訊讀取出來,【接受簡訊】按鈕的Click事件中的代碼如下。
protected void btnResvice_Click(object sender, EventArgs e)
{
//串連裝置
if (Basic.GMS.GSMModemInitNew(txtCOM.Text, txtBTL.Text, null, null, false, txtPower.Text) == false)
{
Page.RegisterStartupScript("","<script>alert('串連失敗!'" + Basic.GMS.GSMModemGetErrorMsg()+"')</script>");
return;
}
//接收簡訊
txtContent.Text = Basic.GMS.GSMModemSMSReadAll(1);
if (txtContent.Text.Length <= 0)
{
Page.RegisterStartupScript("","<script>alert('暫時沒有新的資訊!')</script>");
return;
}
txtSJHM.Text = txtContent.Text.Substring(0, 13);
txtContent.Text = txtContent.Text.Substring(13, txtContent.Text.Length - 13);
}
3.補充說明
因為簡訊貓是串列通訊裝置,必須串列提交簡訊發送,而且提交後必須等到有回應後才能提交下一條,否則會造成簡訊貓死機。如果存在多線程同時並行作業簡訊貓,也會造成簡訊貓死機。即使是針對同一簡訊貓的收發,也必須為一前一後串列,而不能通過收發兩個並發線程來操作。