使用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 |
声明: 本文版权归作者和博客园共有。转载时必须保留此段声明,且在文章页面明显位置给出原文连接地址! |