zoukankan      html  css  js  c++  java
  • 使用SerialPort 对象实现串口拨号器通信[上]

     

    首先,定义 CommandInfo 结构体


    结构体 CommandInfo 用于保存当前 AT 指令的相关信息,代码如下:

        enum CommandDirection
        { 
           None = 0, 
           Read = 1, 
           Write = 2
        }
    
        enum CommandKey
        {
            None = 0, 
            AT = 1, 
            ATD = 2,
            ATH = 3,
            AT_CFUN = 4
        }
    
        struct CommandInfo
        {
            public CommandDirection TransType; // 写入 / 读取
    
            public CommandKey Command;     // 命令类型
    
            public int CommandLength;   // 命令自身长度 (不包含\r\n)
    
            public Byte[] SourceData;   // 数据源
    
            public int SourceDataLength;// 数据源长度 (包含\r\n 等转义字符)
    
            public int sleep100msNumber;// 延时100毫秒数
        }

    然后,定义拨号器 Modem 类


    一个 Modem 对象表示一个拨号器,Modem 对象的成员、属性、委托、构造方法如下:

        private SerialPort m_port;
        private Boolean sending = false;
        private Boolean receiving;
        private string m_portName = "";   // 串口名称
        private int m_boudrate = 0;       // 波特率
    
        private SetCallback m_callBack = null; //返回委托事件
        
        #region 委托
        public delegate void SetCallback(String message);
    
        //委托返回信息
        private void ReturnMessage(String message)
        {
            if (message.Length > 0 && m_callBack != null)
            {
                m_callBack(message);
            }
        }
        #endregion
    
        #region  属性
        //串口名称
        public string PortName
        {
            get { return m_portName; }
            set { m_portName = value; }
        }
    
        // 串行波特率
        public int Boudrate
        {
            get 
            {
                if (0 == this.m_boudrate)
                {
                    this.m_boudrate = this.DefaultBoudrate; //默认波特率
                }
                return m_boudrate; 
            }
            set { m_boudrate = value; }
        }
    
        // 默认串行波特率(只读)
        public virtual int DefaultBoudrate
        {
            get { return 9600; }
        }
        #endregion
    
        #region  构造方法
        public Modem(string _portName, int _baudRate, SetCallback _callBack)
            : this(_portName, _callBack)
        {
            if (_baudRate != 0)
            {
                this.m_boudrate = _baudRate;  // BaudRate 串行波特率
            }
        }
    
        public Modem(string _portName, SetCallback _callBack)
        {
            CreateModem(_portName);
    
            if (_callBack != null) m_callBack = _callBack;
    
            try
            {
                OpenModem();
            }
            catch
            {
                CloseModem();
            }
    
        }
        #endregion

    拨号器所对应的串口的基本方法如下:

        #region 拨号器的基本方法
        private void CreateModem(string portName)
        {
            if (this.m_port == null)
            {
                this.m_port = new SerialPort(portName, this.Boudrate, Parity.None, 8, StopBits.One);
                this.m_port.ReadTimeout = 50000; //50秒超时时间
    
                this.m_port.RtsEnable = true; // 是否启用请求发送 (RTS) 信号
                //Request To Send 是由计算机发送信号到联接的调制解调器,以请示允许发送数据。
    
                //this.m_port.DtrEnable = true; // 是否使(DTR)线有效。
                //Data Terminal Ready 是计算机发送到调制解调器的信号,指示计算机在等待接受传输。 
    
                this.PortName = portName;
            }
        }
        private void CreateModem()
        {
            if (this.m_port == null)
            {
                this.m_port = new SerialPort(this.PortName, this.Boudrate, Parity.None, 8, StopBits.One);
                this.m_port.ReadTimeout = 50000; //50秒超时时间
    
                this.m_port.RtsEnable = true; // 是否启用请求发送 (RTS) 信号
                //Request To Send 是由计算机发送信号到联接的调制解调器,以请示允许发送数据。
    
                //this.m_port.DtrEnable = true; // 是否使(DTR)线有效。
                //Data Terminal Ready 是计算机发送到调制解调器的信号,指示计算机在等待接受传输。 
            }
        }
    
        // Opening modem port
        public Boolean OpenModem()
        {
            CreateModem();
            try
            {
                if (!m_port.IsOpen)
                {
                    this.m_port.Open();
                }
                return true;
            }
            catch (Exception ex)
            {
                //這邊你可以自訂發生例外的處理程序
                ReturnMessage(String.Format("出现异常:{0}", ex.ToString()));
                return false;
            }
        }
    
    
        // Closing modem port
        public void CloseModem()
        {
            try
            {
                if (!sending && this.m_port != null && this.m_port.IsOpen)
                {
                    this.m_port.Close();
                    //ReturnMessage("端口已关闭");
                }
            }
            catch (Exception ex)
            {
                //這邊你可以自訂發生例外的處理程序
                ReturnMessage(String.Format("出现异常:{0}", ex.ToString()));
            }
        }
        #endregion

    拨号器的 “发送命令” 和 “返回接受” 方法是整个Modem 对象的核心,代码如下:

        // 向端口发送命令
        private bool SendData(Object dataInfo)
        {
            if (dataInfo == null) return false;
    
            CommandInfo sourceInfo = (CommandInfo)dataInfo;
    
            string returnString = "";
            bool receiveSate = false;
    
            if (sourceInfo.SourceData != null)
            {
                Byte[] buffer = sourceInfo.SourceData;
                try
                {
                    sending = true;
                    m_port.Write(buffer, 0, buffer.Length);
                    receiving = true;
                    Thread.Sleep(200);
    
                    //comport.DiscardInBuffer();    //清空输入缓冲区
                    //comport.DiscardOutBuffer();   //清空输出缓冲区
    
                    receiveSate = DoReceive(sourceInfo, ref returnString);
    
                    //返回处理
                    switch (sourceInfo.Command)
                    {
                        case CommandKey.AT: // 处理 AT 指令
                            Process_AT_Command(returnString);
                            break;
    
                        case CommandKey.ATD: // 处理 ATD 指令
                            Process_ATD_Command(returnString);
                            break;
    
                        case CommandKey.ATH: // 处理 ATH 指令
                            Process_ATH_Command(returnString);
                            break;
    
                        case CommandKey.AT_CFUN: // 处理 AT_CFUN 指令
                            Process_AT_CFUN_Command(returnString);
                            break;
    
                        case CommandKey.None: //处理 其他未知 指令
                        default:
                            Process_None_Command(returnString);
                            break;
                    }   
                }
                catch (Exception ex)
                {
                    //这里你可以自定义发生例外的处理程序
                    CloseModem();
                    ReturnMessage(String.Format("出现异常:{0}", ex.ToString()));
                }
                finally
                {
                    sending = false;
                }
            }
    
            return receiveSate;
        }
    
    
        // 接受端口返回数据
        private bool DoReceive(CommandInfo dataInfo, ref String returnString)
        {
            List<Byte> tempList = new List<Byte>();
            Byte[] buffer = new Byte[1024];
            Int32 ticks = 0;
            //string returnString = "";
            bool receiveSate = false;
    
            while (receiving)
            {
                Thread.Sleep(100);
                if (m_port.BytesToRead > 0)
                {
                    try
                    {
                        Int32 receivedLength = m_port.Read(buffer, 0, buffer.Length);
                        Array.Resize(ref buffer, receivedLength);
                        foreach (Byte item in buffer)
                        {
                            if (item != 0x0d && item != 0x0a)
                            {
                                tempList.Add(item);
                            }
                        }
                        //tempList.AddRange(buffer);
                        Array.Resize(ref buffer, 1024);
                    }
                    catch (TimeoutException timeEx)
                    {
                        //這邊你可以自訂發生例外的處理程序
                        tempList.Clear();
                        m_port.DiscardInBuffer();    //清空输入缓冲区
                        receiving = false;
                        ReturnMessage(String.Format("读取超时:{0}", timeEx.ToString()));
                    }
                    catch (Exception ex)
                    {
                        //這邊你可以自訂發生例外的處理程序
                        CloseModem();
                        receiving = false;
                        ReturnMessage(String.Format("出现异常:{0}", ex.ToString()));
                    }
                }
    
                //返回字符 > 发送字符
                if (tempList.Count > dataInfo.CommandLength)
                {
                    //(测试使用) 返回的所有字符串信息
                    //string returnAllString = System.Text.Encoding.Default.GetString(tempList.ToArray()); 
    
                    Byte[] returnByte = new Byte[tempList.Count - dataInfo.CommandLength];
                    Array.Copy(tempList.ToArray(), dataInfo.CommandLength, returnByte, 0, returnByte.Length);
    
                    //返回的字符串信息(剔除了发送字符)
                    returnString = System.Text.Encoding.Default.GetString(returnByte).ToUpper();
                    //returnString = System.Text.Encoding.Unicode.GetString(returnByte).ToUpper();
                    receiving = false;
                    receiveSate = true;  //表示成功接收返回
                }
    
                ticks++;
                if (ticks >= dataInfo.sleep100msNumber)
                {
                    receiving = false;
                    ReturnMessage("接收延时过久!");
                }
            }
    
            return receiveSate;
    
            //返回数据监听结束后的业务处理
            //ProcessReceive(dataInfo, returnString);
        }

    需要使用的 AT 指令定义的方法如下:

        // 检测当前端口是否安装有拨号器
        public bool CheckPortExistModem()
        {
            bool hasModem = false;
    
            if (!sending && OpenModem())
            {
                CommandInfo dataInfo = new CommandInfo();
                dataInfo.TransType = CommandDirection.Write;
                dataInfo.Command = CommandKey.AT;
                dataInfo.CommandLength = 2;
                dataInfo.SourceDataLength = 4;
                dataInfo.SourceData = ConvertStringToBytes("AT\r\n");
                dataInfo.sleep100msNumber = 10;
    
                //Thread t = CreateThread();
                //t.Start(dataInfo); //xg
    
                hasModem = SendData(dataInfo); //不使用多线程的方式
            }
    
            return hasModem;
        }
    
    
        // 发送拨号指令唤醒上位机
        public void DialingNumberToModem(string _number)
        {
            if (!sending && OpenModem())
            {
                CommandInfo dataInfo = new CommandInfo();
                dataInfo.TransType = CommandDirection.Write;
                dataInfo.Command = CommandKey.ATD;
                dataInfo.CommandLength = 15;
                dataInfo.SourceDataLength = 17;
                dataInfo.SourceData = ConvertStringToBytes(string.Format("ATD{0};\r\n", _number));
                dataInfo.sleep100msNumber = 500;
    
                //Thread t = CreateThread();
                //t.Start(dataInfo);
    
                SendData(dataInfo); //不使用多线程的方式
            }
        }
    
        // 发送挂机指令停止拨号
        private void StopDialingNumberToModem()
        {
            if (OpenModem())  // if (!sending && OpenModem())
            {
                CommandInfo dataInfo = new CommandInfo();
                dataInfo.TransType = CommandDirection.Write;
                dataInfo.Command = CommandKey.ATH;
                dataInfo.CommandLength = 3;
                dataInfo.SourceDataLength = 5;
                dataInfo.SourceData = ConvertStringToBytes("ATH\r\n");
                dataInfo.sleep100msNumber = 20;
    
                //Thread t = CreateThread();
                //t.Start(dataInfo);
    
                SendData(dataInfo); //不使用多线程的方式
            }
        }
    
        //重启拨号器
        private void RebootToModem()
        {
            if (OpenModem())  // if (!sending && OpenModem())
            {
                CommandInfo dataInfo = new CommandInfo();
                dataInfo.TransType = CommandDirection.Write;
                dataInfo.Command = CommandKey.AT_CFUN;
                dataInfo.CommandLength = 11;
                dataInfo.SourceDataLength = 15;  // AT+CFUN=1,1\r\nOK
                dataInfo.SourceData = ConvertStringToBytes("AT+CFUN=1,1\r\n");
                dataInfo.sleep100msNumber = 100;
    
                //Thread t = CreateThread();
                //t.Start(dataInfo);
    
                SendData(dataInfo); //不使用多线程的方式
            }
        }

        private Byte[] ConvertStringToBytes(String dataString)
        {

           //if (Regex.IsMatch(dataString, "([^0-9a-fA-F])"))
           //{
           //    //表示有不符的字元
           //    ReturnMessage("Block 数据错误");
           //    return null;
           //}

           byte[] buff = Encoding.ASCII.GetBytes(dataString);
           return buff;
       }

    对应的 AT 指令返回数据处理如下:

            //处理 AT 指令
            private void Process_AT_Command(String returnString)
            {
                if (returnString == "OK")
                {
                    //拨号器正常
                    ReturnMessage(String.Format("AT指令正常,返回信息:{0}", returnString));
                }
                else
                {
                    ReturnMessage(String.Format("AT指令异常,返回信息:{0}", 
                                         returnString != "" ? returnString : ""));
                }
            }
    
            //处理 ATD 指令
            private void Process_ATD_Command(String returnString)
            {
                switch (returnString)
                {
                    case "ERROR":  //当拨打电话不成功时,返回 ERROR
                    case "NO DIALTONE": //未检测到拨号音,返回 NO DIALTONE
                        ReturnMessage(String.Format("返回信息:{0},重启拨号器...", returnString));
                        RebootToModem(); //重启拨号器
                        break;
    
                    case "NO CARRIER": //被叫方接通电话,然后主动挂机,信道已释放。返回 NO CARRIER
                        ReturnMessage(String.Format("返回信息:{0}", returnString));
                        break;
    
                    case "BUSY":  //检测到占线信号,直接挂机。返回 BUSY 
                    case "OK":    //当接通电话时,返回 OK 
                    case "":
                    default:
                        ReturnMessage(String.Format("返回信息:{0},发送挂机指令...", 
                                             returnString != "" ? returnString : ""));
                        StopDialingNumberToModem();  //发送挂机指令停止拨号 ATH
                        break;
                }
            }
    
            //处理 ATH 指令
            private void Process_ATH_Command(String returnString)
            {
                ReturnMessage(String.Format("已挂机,返回信息:{0}", 
                                     returnString != "" ? returnString : ""));
            }
    
            //处理 AT_CFUN 指令
            private void Process_AT_CFUN_Command(String returnString)
            {
                if (returnString == "OK^SYSSTART")
                {
                    //重启成功
                    ReturnMessage(String.Format("拨号器重启成功,返回信息:{0}", returnString));
                }
                else ReturnMessage(String.Format("拨号器重启异常,返回信息:{0}", 
                                          returnString != "" ? returnString : ""));
            }
    
            //处理 其他未知 指令
            private void Process_None_Command(String returnString)
            {
                ReturnMessage(String.Format("拨号器其他情况,返回信息:{0}", 
                                     returnString != "" ? returnString : ""));
            }

    整个 Modem 类的代码如下:

    Modem.cs 整体代码
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO.Ports;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace RequestResponse001CS
    {
        public class Modem
        {
            private SerialPort m_port;
            private Boolean sending = false;
            private Boolean receiving;
    
            private string m_portName = "";   // 串口名称
            private int m_boudrate = 0;       // 波特率
            //private bool m_isWorking = false; // 是否正在使用
            //private string m_answer = "";     // 返回数据缓冲区
            //private DateTime lastUseTime = DateTime.MinValue; //最后一次使用时间
    
            private SetCallback m_callBack = null; //返回委托事件
            
            #region 委托
            public delegate void SetCallback(String message);
    
            //委托返回信息
            private void ReturnMessage(String message)
            {
                if (message.Length > 0 && m_callBack != null)
                {
                    m_callBack(message);
                }
            }
            #endregion
    
            #region  属性
    
            //串口名称
            public string PortName
            {
                get { return m_portName; }
                set { m_portName = value; }
            }
    
            //是否正在使用
            //public bool IsWorking
            //{
            //    get { return m_isWorking; }
            //    set { m_isWorking = value; }
            //}
    
            // 串行波特率
            public int Boudrate
            {
                get 
                {
                    if (0 == this.m_boudrate)
                    {
                        this.m_boudrate = this.DefaultBoudrate; //默认波特率
                    }
                    return m_boudrate; 
                }
                set { m_boudrate = value; }
            }
    
            // 默认串行波特率(只读)
            public virtual int DefaultBoudrate
            {
                get { return 9600; }
            }
    
            // Modem answer to command (只读)
            //public string Answer
            //{
            //    get { return m_answer; }
            //}
    
            //当前拨号器能否使用 (解决连续使用拨号问题)
            //public bool EnableWork
            //{
            //    get
            //    {
            //        TimeSpan span = DateTime.Now - lastUseTime;
            //        return span.TotalSeconds >= 60;
            //    }
            //    //set { enableUse = value; }
            //}
    
            #endregion
    
            #region  构造方法
            public Modem(string _portName, int _baudRate, SetCallback _callBack)
                : this(_portName, _callBack)
            {
                if (_baudRate != 0)
                {
                    this.m_boudrate = _baudRate;  // BaudRate 串行波特率
                }
            }
    
            public Modem(string _portName, SetCallback _callBack)
            {
                CreateModem(_portName);
    
                if (_callBack != null) m_callBack = _callBack;
    
                try
                {
                    OpenModem();
                }
                catch
                {
                    CloseModem();
                }
    
            }
            #endregion
    
            #region 拨号器的基本方法
            private void CreateModem(string portName)
            {
                if (this.m_port == null)
                {
                    this.m_port = new SerialPort(portName, this.Boudrate, Parity.None, 8, StopBits.One);
                    this.m_port.ReadTimeout = 50000; //50秒超时时间
    
                    this.m_port.RtsEnable = true; // 是否启用请求发送 (RTS) 信号
                    //Request To Send 是由计算机发送信号到联接的调制解调器,以请示允许发送数据。
    
                    //this.m_port.DtrEnable = true; // 是否使(DTR)线有效。
                    //Data Terminal Ready 是计算机发送到调制解调器的信号,指示计算机在等待接受传输。 
    
                    this.PortName = portName;
                }
            }
            private void CreateModem()
            {
                if (this.m_port == null)
                {
                    this.m_port = new SerialPort(this.PortName, this.Boudrate, Parity.None, 8, StopBits.One);
                    this.m_port.ReadTimeout = 50000; //50秒超时时间
    
                    this.m_port.RtsEnable = true; // 是否启用请求发送 (RTS) 信号
                    //Request To Send 是由计算机发送信号到联接的调制解调器,以请示允许发送数据。
    
                    //this.m_port.DtrEnable = true; // 是否使(DTR)线有效。
                    //Data Terminal Ready 是计算机发送到调制解调器的信号,指示计算机在等待接受传输。 
                }
            }
    
            // Opening modem port
            public Boolean OpenModem()
            {
                CreateModem();
                try
                {
                    if (!m_port.IsOpen)
                    {
                        this.m_port.Open();
                    }
                    return true;
                }
                catch (Exception ex)
                {
                    //這邊你可以自訂發生例外的處理程序
                    ReturnMessage(String.Format("出现异常:{0}", ex.ToString()));
                    return false;
                }
            }
    
    
            // Closing modem port
            public void CloseModem()
            {
                try
                {
                    if (!sending && this.m_port != null && this.m_port.IsOpen)
                    {
                        this.m_port.Close();
                        //ReturnMessage("端口已关闭");
                    }
                }
                catch (Exception ex)
                {
                    //這邊你可以自訂發生例外的處理程序
                    ReturnMessage(String.Format("出现异常:{0}", ex.ToString()));
                }
            }
            #endregion
    
            #region 所有发送命令方法 commands method
    
            // 检测当前端口是否安装有拨号器
            public bool CheckPortExistModem()
            {
                bool hasModem = false;
    
                if (!sending && OpenModem())
                {
                    CommandInfo dataInfo = new CommandInfo();
                    dataInfo.TransType = CommandDirection.Write;
                    dataInfo.Command = CommandKey.AT;
                    dataInfo.CommandLength = 2;
                    dataInfo.SourceDataLength = 4;
                    dataInfo.SourceData = ConvertStringToBytes("AT\r\n");
                    dataInfo.sleep100msNumber = 10;
    
                    //Thread t = CreateThread();
                    //t.Start(dataInfo); //xg
    
                    hasModem = SendData(dataInfo); //不使用多线程的方式
                }
    
                return hasModem;
            }
    
    
            // 发送拨号指令唤醒上位机
            public void DialingNumberToModem(string _number)
            {
                if (!sending && OpenModem())
                {
                    CommandInfo dataInfo = new CommandInfo();
                    dataInfo.TransType = CommandDirection.Write;
                    dataInfo.Command = CommandKey.ATD;
                    dataInfo.CommandLength = 15;
                    dataInfo.SourceDataLength = 17;
                    dataInfo.SourceData = ConvertStringToBytes(string.Format("ATD{0};\r\n", _number));
                    dataInfo.sleep100msNumber = 500;
    
                    //Thread t = CreateThread();
                    //t.Start(dataInfo);
    
                    SendData(dataInfo); //不使用多线程的方式
                }
            }
    
            // 发送挂机指令停止拨号
            private void StopDialingNumberToModem()
            {
                if (OpenModem())  // if (!sending && OpenModem())
                {
                    CommandInfo dataInfo = new CommandInfo();
                    dataInfo.TransType = CommandDirection.Write;
                    dataInfo.Command = CommandKey.ATH;
                    dataInfo.CommandLength = 3;
                    dataInfo.SourceDataLength = 5;
                    dataInfo.SourceData = ConvertStringToBytes("ATH\r\n");
                    dataInfo.sleep100msNumber = 20;
    
                    //Thread t = CreateThread();
                    //t.Start(dataInfo);
    
                    SendData(dataInfo); //不使用多线程的方式
                }
            }
    
            //重启拨号器
            private void RebootToModem()
            {
                if (OpenModem())  // if (!sending && OpenModem())
                {
                    CommandInfo dataInfo = new CommandInfo();
                    dataInfo.TransType = CommandDirection.Write;
                    dataInfo.Command = CommandKey.AT_CFUN;
                    dataInfo.CommandLength = 11;
                    dataInfo.SourceDataLength = 15;  // AT+CFUN=1,1\r\nOK
                    dataInfo.SourceData = ConvertStringToBytes("AT+CFUN=1,1\r\n");
                    dataInfo.sleep100msNumber = 100;
    
                    //Thread t = CreateThread();
                    //t.Start(dataInfo);
    
                    SendData(dataInfo); //不使用多线程的方式
                }
            }
    
    
            //private Thread CreateThread()
            //{
            //    Thread t = new Thread(SendData);
            //    t.IsBackground = true;
            //    return t;
            //}
    
    
            // 向端口发送命令
            private bool SendData(Object dataInfo)
            {
                if (dataInfo == null) return false;
    
                CommandInfo sourceInfo = (CommandInfo)dataInfo;
    
                string returnString = "";
                bool receiveSate = false;
    
                if (sourceInfo.SourceData != null)
                {
                    Byte[] buffer = sourceInfo.SourceData;
                    try
                    {
                        sending = true;
                        m_port.Write(buffer, 0, buffer.Length);
                        receiving = true;
                        Thread.Sleep(200);
    
                        //comport.DiscardInBuffer();    //清空输入缓冲区
                        //comport.DiscardOutBuffer();   //清空输出缓冲区
    
                        receiveSate = DoReceive(sourceInfo, ref returnString);
    
                        //返回处理
                        switch (sourceInfo.Command)
                        {
                            case CommandKey.AT: // 处理 AT 指令
                                Process_AT_Command(returnString);
                                break;
    
                            case CommandKey.ATD: // 处理 ATD 指令
                                Process_ATD_Command(returnString);
                                break;
    
                            case CommandKey.ATH: // 处理 ATH 指令
                                Process_ATH_Command(returnString);
                                break;
    
                            case CommandKey.AT_CFUN: // 处理 AT_CFUN 指令
                                Process_AT_CFUN_Command(returnString);
                                break;
    
                            case CommandKey.None: //处理 其他未知 指令
                            default:
                                Process_None_Command(returnString);
                                break;
                        }   
                    }
                    catch (Exception ex)
                    {
                        //这里你可以自定义发生例外的处理程序
                        CloseModem();
                        ReturnMessage(String.Format("出现异常:{0}", ex.ToString()));
                    }
                    finally
                    {
                        sending = false;
                    }
                }
    
                return receiveSate;
            }
    
            // 接受端口返回数据
            private bool DoReceive(CommandInfo dataInfo, ref String returnString)
            {
                List<Byte> tempList = new List<Byte>();
                Byte[] buffer = new Byte[1024];
                Int32 ticks = 0;
                //string returnString = "";
                bool receiveSate = false;
    
                while (receiving)
                {
                    Thread.Sleep(100);
                    if (m_port.BytesToRead > 0)
                    {
                        try
                        {
                            Int32 receivedLength = m_port.Read(buffer, 0, buffer.Length);
                            Array.Resize(ref buffer, receivedLength);
                            foreach (Byte item in buffer)
                            {
                                if (item != 0x0d && item != 0x0a)
                                {
                                    tempList.Add(item);
                                }
                            }
                            //tempList.AddRange(buffer);
                            Array.Resize(ref buffer, 1024);
                        }
                        catch (TimeoutException timeEx)
                        {
                            //這邊你可以自訂發生例外的處理程序
                            tempList.Clear();
                            m_port.DiscardInBuffer();    //清空输入缓冲区
                            receiving = false;
                            ReturnMessage(String.Format("读取超时:{0}", timeEx.ToString()));
                        }
                        catch (Exception ex)
                        {
                            //這邊你可以自訂發生例外的處理程序
                            CloseModem();
                            receiving = false;
                            ReturnMessage(String.Format("出现异常:{0}", ex.ToString()));
                        }
                    }
    
                    //返回字符 > 发送字符
                    if (tempList.Count > dataInfo.CommandLength)
                    {
                        //(测试使用) 返回的所有字符串信息
                        //string returnAllString = System.Text.Encoding.Default.GetString(tempList.ToArray()); 
    
                        Byte[] returnByte = new Byte[tempList.Count - dataInfo.CommandLength];
                        Array.Copy(tempList.ToArray(), dataInfo.CommandLength, returnByte, 0, returnByte.Length);
    
                        //返回的字符串信息(剔除了发送字符)
                        returnString = System.Text.Encoding.Default.GetString(returnByte).ToUpper();
                        //returnString = System.Text.Encoding.Unicode.GetString(returnByte).ToUpper();
                        receiving = false;
                        receiveSate = true;  //表示成功接收返回
                    }
    
                    ticks++;
                    if (ticks >= dataInfo.sleep100msNumber)
                    {
                        receiving = false;
                        ReturnMessage("接收延时过久!");
                    }
                }
    
                return receiveSate;
    
                //返回数据监听结束后的业务处理
                //ProcessReceive(dataInfo, returnString);
            }
    
            //处理 AT 指令
            private void Process_AT_Command(String returnString)
            {
                if (returnString == "OK")
                {
                    //拨号器正常
                    ReturnMessage(String.Format("AT指令正常,返回信息:{0}", returnString));
                }
                else
                {
                    ReturnMessage(String.Format("AT指令异常,返回信息:{0}", 
                                         returnString != "" ? returnString : ""));
                }
            }
    
            //处理 ATD 指令
            private void Process_ATD_Command(String returnString)
            {
                switch (returnString)
                {
                    case "ERROR":  //当拨打电话不成功时,返回 ERROR
                    case "NO DIALTONE": //未检测到拨号音,返回 NO DIALTONE
                        ReturnMessage(String.Format("返回信息:{0},重启拨号器...", returnString));
                        RebootToModem(); //重启拨号器
                        break;
    
                    case "NO CARRIER": //被叫方接通电话,然后主动挂机,信道已释放。返回 NO CARRIER
                        ReturnMessage(String.Format("返回信息:{0}", returnString));
                        break;
    
                    case "BUSY":  //检测到占线信号,直接挂机。返回 BUSY 
                    case "OK":    //当接通电话时,返回 OK 
                    case "":
                    default:
                        ReturnMessage(String.Format("返回信息:{0},发送挂机指令...", 
                                             returnString != "" ? returnString : ""));
                        StopDialingNumberToModem();  //发送挂机指令停止拨号 ATH
                        break;
                }
            }
    
            //处理 ATH 指令
            private void Process_ATH_Command(String returnString)
            {
                ReturnMessage(String.Format("已挂机,返回信息:{0}", 
                                     returnString != "" ? returnString : ""));
            }
    
            //处理 AT_CFUN 指令
            private void Process_AT_CFUN_Command(String returnString)
            {
                if (returnString == "OK^SYSSTART")
                {
                    //重启成功
                    ReturnMessage(String.Format("拨号器重启成功,返回信息:{0}", returnString));
                }
                else ReturnMessage(String.Format("拨号器重启异常,返回信息:{0}", 
                                          returnString != "" ? returnString : ""));
            }
    
            //处理 其他未知 指令
            private void Process_None_Command(String returnString)
            {
                ReturnMessage(String.Format("拨号器其他情况,返回信息:{0}", 
                                     returnString != "" ? returnString : ""));
            }
    
            //处理监听返回业务
            //private void ProcessReceive(CommandInfo dataInfo, String returnString)
            //{
                   
            //}
    
    
            private Byte[] ConvertStringToBytes(String dataString)
            {
    
                //if (Regex.IsMatch(dataString, "([^0-9a-fA-F])"))
                //{
                //    //表示有不符的字元
                //    ReturnMessage("Block 数据错误");
                //    return null;
                //}
    
                byte[] buff = Encoding.ASCII.GetBytes(dataString);
                return buff;
            }
    
    
            /// <summary>
            /// 直接向端口发送命令!
            /// </summary>
            /// <param name="command">命令字符串</param>
            private void SendCommandToModem(string command)
            {
                if (!this.m_port.IsOpen) this.OpenModem();
    
                byte[] buff = Encoding.ASCII.GetBytes(command);
                try
                {
                    this.m_port.Write(buff, 0, buff.Length);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
    
            #endregion
        }
    }

    最后,定义 FormModem 测试页面


    测试页面 FormModem 代码如下:

    using System;
    using System.Windows.Forms;
    
    namespace RequestResponse001CS
    {
        public partial class FormModem : Form
        {
            public FormModem()
            {
                InitializeComponent();
            }
    
            Modem modem;
            private Modem.SetCallback call;
    
            private void Form1_Load(object sender, EventArgs e)
            {
                //sending = false;
                call = new Modem.SetCallback(this.TakeControl);
                modem = new Modem("COM8", call);
            }
    
    
            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 Button_AT_Click(object sender, EventArgs e)
            {
                modem.CheckPortExistModem();
            }
    
            private void Button_ATD_Click(object sender, EventArgs e)
            {
                if (TextBox1.Text.Trim() != "")
                {
                    modem.DialingNumberToModem(TextBox1.Text.Trim());
                }
                else modem.DialingNumberToModem("135xxxxxxxxxxx");
            }
    
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                modem.CloseModem();
            }
    
        }
    }

    测试页面截图如下:

    (完)

    作者: XuGang   网名:钢钢
    出处: http://xugang.cnblogs.com
    声明: 本文版权归作者和博客园共有。转载时必须保留此段声明,且在文章页面明显位置给出原文连接地址!
  • 相关阅读:
    2.4学习
    2.3学习
    2.2学习
    2.1学习
    公文流转系统 模拟
    《GCC编译器的使用以及静态库和动态库的制作与使用》
    《驱动调试
    《海思3521D
    《驱动调试
    《驱动调试
  • 原文地址:https://www.cnblogs.com/xugang/p/3075892.html
Copyright © 2011-2022 走看看