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