zoukankan      html  css  js  c++  java
  • 使用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
    声明: 本文版权归作者和博客园共有。转载时必须保留此段声明,且在文章页面明显位置给出原文连接地址!
  • 相关阅读:
    关于我 — About Me
    《这样说就对了》读书笔记
    LOMA280保险原理读书笔记
    .NET单元测试的艺术-3.测试代码
    .NET单元测试的艺术-2.核心技术
    .NET单元测试的艺术-1.入门
    《人人都该买保险》读书笔记
    借助 Lucene.Net 构建站内搜索引擎(下)
    借助 Lucene.Net 构建站内搜索引擎(上)
    自己动手写一个简单的MVC框架(第二版)
  • 原文地址:https://www.cnblogs.com/xugang/p/3075992.html
Copyright © 2011-2022 走看看