使用SerialPort 對象實現串口撥號器通信[下]
定義 ModemManager 調度管理類
ModemManager 類用于對所有 Modem 對象進行管理和調度使用。ModemManager 類代碼如下:
using System; using System.Collections.Generic; using System.Text; using System.IO.Ports; using System.Threading; namespace RequestResponse001CS { // 撥號器管理者 public class ModemManager { //已經安裝了撥號器的串口對象 private List<Modem> modemCollection = null; // ModemCollection 的調度編號 private int modemNumber = -1; //當前有無可使用的串口撥號器 private bool hasEnabled = false; //串口撥號器的重新檢測間隔分鐘 private int reCheckMinutes = 30; //默認30分鐘 //波特率配置列表 private Dictionary<string, int> boudrateCollection = null; //獲得當前時間 private DateTime checkDateTime = DateTime.Now; private ManagerCallback m_callBack = null; //返回委托事件 #region 委托 public delegate void ManagerCallback(String message); //委托返回信息 private void ReturnMessage(String message) { if (message.Length > 0 && m_callBack != null) { m_callBack(message); } } #endregion #region 屬性 public List<Modem> ModemCollection { get { return modemCollection; } } //可使用的撥號器個數 public int EnabledCount { get { if (modemCollection == null) return 0; else return modemCollection.Count; } } public bool HasEnabled { get { return hasEnabled; } //set { hasPort = value; } } //波特率配置列表 public Dictionary<string, int> BoudrateCollection { get { return boudrateCollection; } set { boudrateCollection = value; } } //串口撥號器的重新檢測間隔分鐘 public int ReCheckMinutes { get { return reCheckMinutes; } set { reCheckMinutes = value; } } #endregion #region 構造方法 public ModemManager(ManagerCallback callBack) { if (callBack != null) m_callBack = callBack; } public ModemManager(int reCheckMinutes, ManagerCallback callBack) { this.ReCheckMinutes = reCheckMinutes; if (callBack != null) m_callBack = callBack; } public ModemManager(Dictionary<string, int> boudrateCollection, ManagerCallback callBack) { this.BoudrateCollection = boudrateCollection; if (callBack != null) m_callBack = callBack; } public ModemManager(Dictionary<string, int> boudrateCollection, int reCheckMinutes,ManagerCallback callBack) { this.BoudrateCollection = boudrateCollection; this.ReCheckMinutes = reCheckMinutes; if (callBack != null) m_callBack = callBack; } #endregion 構造方法 #region 調度方法 /// <summary> /// 調用撥號器 /// </summary> /// <param name="cardNumber"></param> public void ModemInvoking(string cardNumber) { if (hasEnabled == false) { // 獲得串口上已經安裝了撥號器的對象 this.GetModemCollection(); } if (hasEnabled == true) { this.ModemCalling(cardNumber); } //定期檢測串口列表 if (checkDateTime.AddMinutes(ReCheckMinutes) <= DateTime.Now) { // 重新獲得串口上已經安裝了撥號器的對象 this.GetModemCollection(); checkDateTime = DateTime.Now; } } /// <summary> /// 獲得串口上安裝了撥號器的對象 /// </summary> public void GetModemCollection() { if (modemCollection == null) { modemCollection = new List<Modem>(); } int modemCollectionCount = modemCollection.Count; //步驟一: 重新獲得所有的串口名稱(列表) string[] portNames = SerialPort.GetPortNames(); //如果當前串口數目 > 正在使用的COM if (portNames.Length > modemCollectionCount) { ReturnMessage("正在檢測可以使用的撥號器..."); //測試使用 foreach (string portName in portNames) { //當前串口名是否存在撥號列表中 bool existModem = false; if (modemCollectionCount > 0) { existModem = modemCollection.Exists(delegate(Modem myModem) { return portName == myModem.PortName; }); } //如果當前串口名不存在撥號列表中,則重新檢測! if (!existModem) { ReturnMessage("正在檢測:" + portName); //測試使用 AddModemToCollection(portName); } } } // 判斷當前計算機有無可使用串口端 hasEnabled = modemCollection.Count <= 0 ? false : true; } /// <summary> /// 對撥號器的調度使用 /// </summary> private void ModemCalling(string cardNumber) { if (modemCollection == null) return; // 等待線程進入 Monitor.Enter(modemCollection); Modem modem = null; try { //獲得當前調用的串口對象的索引號 int number = GetModemNumber(); if (number >= 0) //判斷是否存在撥號器 { modem = modemCollection[number]; if (modem != null) // && !modem.IsWorking) { ReturnMessage(string.Format("{0} 正在對 SIM卡:{1} 進行撥號...", modem.PortName,cardNumber)); modem.DialingNumberToModem(cardNumber); //對 SIM 進行撥號,喚醒上位機 } } else { ReturnMessage("沒有可使用的撥號器,重新對端口進行檢測..."); this.GetModemCollection(); } } catch { //再一次檢查該 COM 能否使用! (范工提議) if (modem != null) { string portName = modem.PortName; modemCollection.Remove(modem); //從可用列表去除 modem.CloseModem(); AddModemToCollection(portName); } } finally { if (modemCollection != null) { // 通知其它對象 Monitor.Pulse(modemCollection); // 釋放對象鎖 Monitor.Exit(modemCollection); } } } /// <summary> /// 獲得對 ModemCollection 的調度編號 /// </summary> /// <returns></returns> private int GetModemNumber() { lock (this) { if (modemNumber + 1 >= modemCollection.Count) { if (modemCollection.Count == 0) modemNumber = -1; else modemNumber = 0; } else { modemNumber++; } return modemNumber; } } /// <summary> /// 添加 Modem 到 modemCollection /// </summary> private void AddModemToCollection(string portName) { Modem myModem = null; //是否設置波特率? if (boudrateCollection != null && boudrateCollection.ContainsKey(portName) && boudrateCollection[portName] != 0) { myModem = new Modem(portName, boudrateCollection[portName], ReturnMessage); } else { myModem = new Modem(portName, ReturnMessage); } bool hasModem = myModem.CheckPortExistModem(); if (hasModem) { modemCollection.Add(myModem); } else { myModem.CloseModem(); myModem = null; } } /// <summary> /// 釋放所有的串口資源 /// </summary> public void CloseModemCollection() { if (modemCollection != null) { for (int i = 0; i < modemCollection.Count; i++) { modemCollection[i].CloseModem(); modemCollection[i] = null; } modemCollection = null; } if (boudrateCollection != null) { boudrateCollection = null; } } #endregion } }
定義 FormModemManager 測試界面類
測試界面 FormModemManager 類用于對 ModemManager 對象進行測試,代碼如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Threading; namespace RequestResponse001CS { public partial class FormModemManager : Form { public FormModemManager() { InitializeComponent(); } ModemManager ModemManager; Thread thread; private void FormModemManager_Load(object sender, EventArgs e) { ModemManager = new ModemManager(5, TakeControl); } public void TakeControl(string message) { if (this.InvokeRequired) { Modem.SetCallback d = new Modem.SetCallback(TakeControl); this.Invoke(d, new object[] { message }); } else { //MessageBox.Show(message); this.txtMessageShow.Text = this.txtMessageShow.Text + message + "\r\n" ; this.txtMessageShow.Select(this.txtMessageShow.Text.Length, 0); this.txtMessageShow.ScrollToCaret(); } } private void FormModemManager_FormClosing(object sender, FormClosingEventArgs e) { if (thread != null) { thread.Abort(); } } private void Button_Run_Click(object sender, EventArgs e) { thread = new Thread(new ThreadStart(Run)); thread.Start(); } private void Run() { try { // 獲得串口上已經安裝了撥號器的對象 ModemManager.GetModemCollection(); if (ModemManager.HasEnabled == false) { TakeControl("當前計算機無可使用的串口撥號器!"); } else { TakeControl("當前計算機可使用的撥號器如下:"); List<Modem> modemCollection = ModemManager.ModemCollection; for (int i = 0; i < modemCollection.Count; i++) { Modem modem = modemCollection[i]; TakeControl(string.Format("端口名:{0},波特率:{1}", modem.PortName, modem.Boudrate.ToString())); } } while (ModemManager.HasEnabled) { // 調用撥號器 if (string.IsNullOrEmpty(txtCardNumber.Text.Trim())) { ModemManager.ModemInvoking("135xxxxxxxx"); // SIM 卡號 } else ModemManager.ModemInvoking(txtCardNumber.Text.Trim()); Thread.Sleep(5000); } TakeControl("程序運行結束!"); } finally { // 釋放所有串口資源組件 ModemManager.CloseModemCollection(); } } //運行停止 private void Button_Stop_Click(object sender, EventArgs e) { if (ModemManager != null) { ModemManager.CloseModemCollection(); } } } }
測試頁面截圖如下:

參考文章 :http://www.dotblogs.com.tw/billchung/category/5702.aspx?Show=All
源碼下載:http://download.csdn.net/detail/guangrou/5375603
(完)
| 作者: XuGang 網名:鋼鋼 |
| 出處: http://xugang.cnblogs.com |
| 聲明: 本文版權歸作者和博客園共有。轉載時必須保留此段聲明,且在文章頁面明顯位置給出原文連接地址! |
浙公網安備 33010602011771號