使用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 |
| 聲明: 本文版權歸作者和博客園共有。轉載時必須保留此段聲明,且在文章頁面明顯位置給出原文連接地址! |

浙公網安備 33010602011771號