C# 使用猫拨打电话
阅读原文时间:2023年07月11日阅读:1

主窗口一个textbox与btnstart按钮

代码是使用别人!只是去掉部分不用的!只用于拨号!用于辅助打电话!

form1

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;
using System.Data;
using System.Drawing;

using System.Threading;

namespace DialUp
{
public partial class Form1 : Form
{
static String str11;
public Form1()
{
InitializeComponent();
}

    private void button1\_Click(object sender, EventArgs e)
    {
        if (btnStart.Text == "开始")
        {

            str11 = textBox1.Text;
            btnStart.Text = "停止";
            timer2.Enabled = true;

            int ModemCount = int.Parse(GetConfig("ComCount"));
            ; i < ModemCount; i++)
            {
                queue.Enqueue(i + );
            }
        }
        else
        {
            btnStart.Text = "开始";
            timer2.Enabled = false;

            )
            {
                try
                {
                    Thread t = queueThread.Dequeue();
                    t.Join();
                    t.Abort();
                }
                catch { }
            }
        }
    }

    private void timer2\_Tick(object sender, EventArgs e)
    {
        )
        {
            Thread t = new Thread(Dial);
            t.Start();

            queueThread.Enqueue(t);
        }
    }
    /// <summary>任务队列</summary>
    private static System.Collections.Generic.Queue<int> queue = new Queue<int>();
    /// <summary>线程队列 </summary>
    private static System.Collections.Generic.Queue<Thread> queueThread = new Queue<Thread>();
    private static System.Text.StringBuilder sbMsg = new StringBuilder();
    private static void Dial()
    {
        int index = queue.Dequeue();
        sbMsg.Insert(, "启动端口" + index + "\\r\\n");

        try
        {

            CommPort port = new CommPort();
            port.PortNum = GetConfig(string.Format("Com\_{0}\_PortNum", index));//端口名称
            port.BaudRate = int.Parse(GetConfig(string.Format("Com\_{0}\_BaudRate", index)));             //串口通信波特率 ,每秒位数
            port.ByteSize = byte.Parse(GetConfig(string.Format("Com\_{0}\_ByteSize", index)));            //数据位
            port.Parity = byte.Parse(GetConfig(string.Format("Com\_{0}\_Parity", index)));              //奇偶校验
            port.StopBits = byte.Parse(GetConfig(string.Format("Com\_{0}\_StopBits", index)));            //停止位
            port.ReadTimeout = ;                                 //读超时时间

            if (!port.Opened)
                port.Open();//打开串口 

            //初始化modem
            string\[\] strInit = GetConfig(string.Format("Com\_{0}\_Init", index)).Split('|');
            foreach (string str in strInit)
            {
                if (str == string.Empty) continue;
                string strData = str + "\\r";
                port.Write(System.Text.Encoding.ASCII.GetBytes(strData));
                //Thread.Sleep(1000);
                port.Read();
            }

            //拨号
            //string strDial = GetConfig(string.Format("Com\_{0}\_Dial", index)) + "\\r";
            string strDial = "ATDT" + str11 + "\\r";
            int dCount = int.Parse(GetConfig(string.Format("Com\_{0}\_dCount", index)));
            int wCount = int.Parse(GetConfig(string.Format("Com\_{0}\_wCount", index)));

            //挂机指令
            string strShutdown = GetConfig(string.Format("Com\_{0}\_Shutdown", index)) + "\\r";

            bool isConntion = false;
            ; k < dCount; k++)
            {
                //拨号
                //port.Write(System.Text.Encoding.ASCII.GetBytes(strShutdown));  //拨号前挂机
                port.Write(System.Text.Encoding.ASCII.GetBytes(strDial));

                //等待20秒
                ; j < wCount; j++)
                {
                    ));

                    sbMsg.Insert(, "端口" + index + "拨号" + k + "/" + j + "\\r\\n");

                    //应答有NO DIALTONE字符表示拨号失败 ,busy表示忙音
                     || strRe.IndexOf()
                    {
                        isConntion = false;
                        sbMsg.Insert(, strRe + "\\r\\n");
                        break;
                    }

                    //没有出现忙音,默认为拨号成功
                    )
                    {
                        isConntion = true;
                        break;
                    }

                    Thread.Sleep();
                }

                //拨号成功
                if (isConntion) break;
            }

            if (isConntion)
            {
                MessageBox.Show("端口" + index + "拨号成功!");
                sbMsg.Insert(, "端口" + index + "拨号成功!\\r\\n");
            }
            else
            {
                MessageBox.Show("端口" + index + "拨号失败!");
                sbMsg.Insert(, "端口" + index + "拨号失败!\\r\\n");
            }

            //挂机,10秒后挂机
            //Thread.Sleep(10000);
            port.Write(System.Text.Encoding.ASCII.GetBytes(strShutdown));

            port.Read();
            port.Close();

            if (MessageBox.Show("是否继续拨号?", "继续拨号", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                queue.Enqueue(index);
            }

        }
        catch (Exception ex)
        {
            sbMsg.Insert(, "打开端口" + index + "错误:" + ex.Message + "\\r\\n");
            return;
        }
    }

    /// <summary>
    /// 读取配置文件
    /// </summary>
    /// <param name="key"></param>
    /// <returns></returns>
    /// 引用 port.BaudRate = int.Parse(GetConfig(string.Format("Com\_{0}\_BaudRate", index)));   port.ByteSize = byte.Parse(GetConfig(string.Format("Com\_{0}\_ByteSize", index)));
    private static string GetConfig(string key)
    {

        System.Configuration.AppSettingsReader config = new System.Configuration.AppSettingsReader();
        return config.GetValue(key, typeof(string)).ToString();
    }

}

}

查看代码

app.config




<!--第一个拨号端口配置-->

<!--端口名称-->
<add key="Com\_1\_PortNum" value="COM3"/>
<!--波特率,最大端口速度-->
<add key="Com\_1\_BaudRate" value="115200"/>
<add key="Com\_1\_ByteSize" value="8"/>
<add key="Com\_1\_Parity" value="0"/>
<add key="Com\_1\_StopBits" value="1"/>
<!--初始化指令-->
<add key="Com\_1\_Init" value="AT|AT&amp;FE0V1S0=0&amp;C1&amp;D2+MR=2;+DR=1;+ER=1;W2|ATS7=60S30=0L1M1+ES=3,0,2;+DS=3;+IFC=2,2;X4"/>
<!--拨号指令 ATDT + 电话号码 比如10000号 则指令为: ATDT10000 -->
<add key="Com\_1\_Dial" value="ATDT015215378122"/>
<!--挂机指令-->
<add key="Com\_1\_Shutdown" value="ATH0"/>
<!--拨号次数-->
<add key="Com\_1\_dCount" value="25"/>
<!--等待时间-->
<add key="Com\_1\_wCount" value="4"/>


查看代码

CommPort.cs类

using System;
using System.Runtime.InteropServices;

namespace DialUp
{
class CommPort
{
///

端口名称
public string PortNum;

    /// <summary> 波特率/每秒位数 </summary>
    public int BaudRate;

    /// <summary>数据位 (5,6,7,8)</summary>
    public byte ByteSize;

    /// <summary>奇偶校验位 0-4=no,odd,even,mark,space</summary>
    public byte Parity;

    /// <summary>停止位 0,1,2 = 1, 1.5, 2 </summary>
    public byte StopBits;

    /// <summary>超时时间</summary>
    public int ReadTimeout;

    /// <summary>指示串口是否打开</summary>
    public bool Opened = false;

    #region WinApi定义

    //comm port win32 file handle
    ;
    //win32 api constants
    private const uint GENERIC\_READ = 0x80000000;
    private const uint GENERIC\_WRITE = 0x40000000;
    ;
    ;

    \[StructLayout(LayoutKind.Sequential)\]
    public struct DCB
    {
        //taken from c struct in platform sdk
        public int DCBlength;           // sizeof(DCB)
        public int BaudRate;            // 指定当前波特率 current baud rate
        // these are the c struct bit fields, bit twiddle flag to set
        public int fBinary;          // 指定是否允许二进制模式,在windows95中必须主TRUE binary mode, no EOF check
        public int fParity;          // 指定是否允许奇偶校验 enable parity checking
        public int fOutxCtsFlow;      // 指定CTS是否用于检测发送控制,当为TRUE是CTS为OFF,发送将被挂起。 CTS output flow control
        public int fOutxDsrFlow;      // 指定CTS是否用于检测发送控制 DSR output flow control
        public int fDtrControl;       // DTR\_CONTROL\_DISABLE值将DTR置为OFF, DTR\_CONTROL\_ENABLE值将DTR置为ON, DTR\_CONTROL\_HANDSHAKE允许DTR"握手" DTR flow control type
        public int fDsrSensitivity;   // 当该值为TRUE时DSR为OFF时接收的字节被忽略 DSR sensitivity
        public int fTXContinueOnXoff; // 指定当接收缓冲区已满,并且驱动程序已经发送出XoffChar字符时发送是否停止。TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动程序已经发送出XoffChar字符中止接收字节之后,发送继续进行。 FALSE时,在接收缓冲区接收到代表缓冲区已空的字节XonChar且驱动程序已经发送出恢复发送的XonChar之后,发送继续进行。XOFF continues Tx
        public int fOutX;               // TRUE时,接收到XoffChar之后便停止发送接收到XonChar之后将重新开始 XON/XOFF out flow control
        public int fInX;           // TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去接收缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去 XON/XOFF in flow control
        public int fErrorChar;     // 该值为TRUE且fParity为TRUE时,用ErrorChar 成员指定的字符代替奇偶校验错误的接收字符 enable error replacement
        public int fNull;          // eTRUE时,接收时去掉空(0值)字节 enable null stripping
        public int fRtsControl;     // RTS flow control  

        /\*RTS\_CONTROL\_DISABLE时,RTS置为OFF
           RTS\_CONTROL\_ENABLE时, RTS置为ON
           RTS\_CONTROL\_HANDSHAKE时,
           当接收缓冲区小于半满时RTS为ON
           当接收缓冲区超过四分之三满时RTS为OFF
           RTS\_CONTROL\_TOGGLE时,
           当接收缓冲区仍有剩余字节时RTS为ON ,否则缺省为OFF\*/

        public int fAbortOnError;   // TRUE时,有错误发生时中止读和写操作 abort on error
        public int fDummy2;        // 未使用 reserved
        public uint flags;
        public ushort wReserved;          // 未使用,必须为0 not currently used
        public ushort XonLim;             // 指定在XON字符发送这前接收缓冲区中可允许的最小字节数 transmit XON threshold
        public ushort XoffLim;            // 指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数 transmit XOFF threshold
        public byte ByteSize;           // 指定端口当前使用的数据位   number of bits/byte, 4-8
        public byte Parity;             // 指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY  0-4=no,odd,even,mark,space
        public byte StopBits;           // 指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS  0,1,2 = 1, 1.5, 2
        public char XonChar;            // 指定用于发送和接收字符XON的值 Tx and Rx XON character
        public char XoffChar;           // 指定用于发送和接收字符XOFF值 Tx and Rx XOFF character
        public char ErrorChar;          // 本字符用来代替接收到的奇偶校验发生错误时的值 error replacement character
        public char EofChar;            // 当没有使用二进制模式时,本字符可用来指示数据的结束 end of input character
        public char EvtChar;            // 当接收到此字符时,会产生一个事件 received event character
        public ushort wReserved1;         // 未使用 reserved; do not use
    }

    /// <summary>
    /// 超时结构
    /// </summary>
    \[StructLayout(LayoutKind.Sequential)\]
    private struct COMMTIMEOUTS
    {
        public int ReadIntervalTimeout;
        public int ReadTotalTimeoutMultiplier;
        public int ReadTotalTimeoutConstant;
        public int WriteTotalTimeoutMultiplier;
        public int WriteTotalTimeoutConstant;
    }

    \[StructLayout(LayoutKind.Sequential)\]
    private struct OVERLAPPED
    {
        public int Internal;
        public int InternalHigh;
        public int Offset;
        public int OffsetHigh;
        public int hEvent;
    }

    /// <summary>
    ///
    /// </summary>
    /// <param name="lpFileName"></param>
    /// <param name="dwDesiredAccess"></param>
    /// <param name="dwShareMode"></param>
    /// <param name="lpSecurityAttributes"></param>
    /// <param name="dwCreationDisposition"></param>
    /// <param name="dwFlagsAndAttributes"></param>
    /// <param name="hTemplateFile"></param>
    /// <returns></returns>
    \[DllImport("kernel32.dll")\]
    private static extern int CreateFile(
      string lpFileName,                        // 要打开的串口名称
      uint dwDesiredAccess,                     // 指定串口的访问方式,一般设置为可读可写方式
      int dwShareMode,                          // 指定串口的共享模式,串口不能共享,所以设置为0
      int lpSecurityAttributes,                 // 设置串口的安全属性,WIN9X下不支持,应设为NULL
      int dwCreationDisposition,                // 对于串口通信,创建方式只能为OPEN\_EXISTING
      int dwFlagsAndAttributes,                 // 指定串口属性与标志,设置为FILE\_FLAG\_OVERLAPPED(重叠I/O操作),指定串口以异步方式通信
      int hTemplateFile                         // 对于串口通信必须设置为NULL
    );

    /// <summary>
    /// 获取串口状态
    /// </summary>
    /// <param name="hFile"></param>
    /// <param name="lpDCB"></param>
    /// <returns></returns>
    \[DllImport("kernel32.dll")\]
    private static extern bool GetCommState(
      int hFile,                                //通信设备句柄
      ref DCB lpDCB                             // 设备控制块DCB
    );

    /// <summary>
    /// 构造串口控制块
    /// </summary>
    /// <param name="lpDef"></param>
    /// <param name="lpDCB"></param>
    /// <returns></returns>
    \[DllImport("kernel32.dll")\]
    private static extern bool BuildCommDCB(
      string lpDef,                             // 设备控制字符串
      ref DCB lpDCB                             // 设备控制块
    );

    /// <summary>
    /// 设置串口状态
    /// </summary>
    /// <param name="hFile"></param>
    /// <param name="lpDCB"></param>
    /// <returns></returns>
    \[DllImport("kernel32.dll")\]
    private static extern bool SetCommState(
      int hFile,                                // 通信设备句柄
      ref DCB lpDCB                             // 设备控制块
    );

    /// <summary>
    /// 获取串口超时时间
    /// </summary>
    /// <param name="hFile"></param>
    /// <param name="lpCommTimeouts"></param>
    /// <returns></returns>
    \[DllImport("kernel32.dll")\]
    private static extern bool GetCommTimeouts(
      int hFile,                                // 通信设备句柄 handle to comm device
      ref COMMTIMEOUTS lpCommTimeouts           // 超时时间 time-out values
    );

    /// <summary>
    /// 设置串口超时时间
    /// </summary>
    /// <param name="hFile"></param>
    /// <param name="lpCommTimeouts"></param>
    /// <returns></returns>
    \[DllImport("kernel32.dll")\]
    private static extern bool SetCommTimeouts(
      int hFile,                                // 通信设备句柄 handle to comm device
      ref COMMTIMEOUTS lpCommTimeouts           // 超时时间 time-out values
    );

    /// <summary>
    ///
    /// </summary>
    /// <param name="hFile"></param>
    /// <param name="lpBuffer"></param>
    /// <param name="nNumberOfBytesToRead"></param>
    /// <param name="lpNumberOfBytesRead"></param>
    /// <param name="lpOverlapped"></param>
    /// <returns></returns>
    \[DllImport("kernel32.dll")\]
    private static extern bool ReadFile(
      int hFile,                                // 通信设备句柄 handle to file
      byte\[\] lpBuffer,                          // 数据缓冲区 data buffer
      int nNumberOfBytesToRead,                 // 多少字节等待读取 number of bytes to read
      ref int lpNumberOfBytesRead,              // 读取多少字节 number of bytes read
      ref OVERLAPPED lpOverlapped               // 溢出缓冲区 overlapped buffer
    );

    /// <summary>
    ///
    /// </summary>
    /// <param name="hFile"></param>
    /// <param name="lpBuffer"></param>
    /// <param name="nNumberOfBytesToWrite"></param>
    /// <param name="lpNumberOfBytesWritten"></param>
    /// <param name="lpOverlapped"></param>
    /// <returns></returns>
    \[DllImport("kernel32.dll")\]
    private static extern bool WriteFile(
      int hFile,                                // 通信设备句柄 handle to file
      byte\[\] lpBuffer,                          // 数据缓冲区 data buffer
      int nNumberOfBytesToWrite,                // 多少字节等待写入 number of bytes to write
      ref int lpNumberOfBytesWritten,           // 已经写入多少字节 number of bytes written
      ref OVERLAPPED lpOverlapped               // 溢出缓冲区 overlapped buffer
    );

    /// <summary>
    /// 关闭接口
    /// </summary>
    /// <param name="hObject"></param>
    /// <returns></returns>
    \[DllImport("kernel32.dll")\]
    private static extern bool CloseHandle(
      int hObject   // handle to object
    );

    /// <summary>
    /// 获取最后一个错误信息
    /// </summary>
    /// <returns></returns>
    \[DllImport("kernel32.dll")\]
    private static extern uint GetLastError();
    #endregion

    /// <summary>
    /// 打开串口
    /// </summary>
    public void Open()
    {

        DCB dcbCommPort = new DCB();
        COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS();

        // 打开串口 OPEN THE COMM PORT.
        hComm = CreateFile(PortNum, GENERIC\_READ | GENERIC\_WRITE, , , OPEN\_EXISTING, , );
        // 如果串口没有打开,就打开 IF THE PORT CANNOT BE OPENED, BAIL OUT.
        if (hComm == INVALID\_HANDLE\_VALUE)
        {
            throw (new ApplicationException("非法操作,不能打开串口!"));
        }

        // 设置通信超时时间 SET THE COMM TIMEOUTS.
        GetCommTimeouts(hComm, ref ctoCommPort);
        ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout;
        ctoCommPort.ReadTotalTimeoutMultiplier = ;
        ctoCommPort.WriteTotalTimeoutMultiplier = ;
        ctoCommPort.WriteTotalTimeoutConstant = ;
        SetCommTimeouts(hComm, ref ctoCommPort);

        // 设置串口 SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS.
        GetCommState(hComm, ref dcbCommPort);
        dcbCommPort.BaudRate = BaudRate;
        dcbCommPort.flags = ;
        //dcb.fBinary=1;
        dcbCommPort.flags |= ;
        )
        {
            //dcb.fParity=1
            dcbCommPort.flags |= ;
        }
        dcbCommPort.Parity = Parity;
        dcbCommPort.ByteSize = ByteSize;
        dcbCommPort.StopBits = StopBits;
        if (!SetCommState(hComm, ref dcbCommPort))
        {
            //uint ErrorNu m= GetLastError();
            throw (new ApplicationException("非法操作,不能打开串口!"));
        }

        //判断端口是否打开
        //DCB dcbCommPort2 = new DCB();
        //GetCommState(hComm, ref dcbCommPort2); 

        Opened = true;
    }

    /// <summary>
    /// 关闭端口
    /// </summary>
    public void Close()
    {
        if (hComm != INVALID\_HANDLE\_VALUE)
        {
            CloseHandle(hComm);
        }
    }

    /// <summary>
    /// 读取指定字节数据
    /// </summary>
    /// <param name="NumBytes"></param>
    /// <returns></returns>
    public byte\[\] Read(int NumBytes)
    {
        byte\[\] BufBytes = new byte\[NumBytes\];
        byte\[\] OutBytes;

        if (hComm != INVALID\_HANDLE\_VALUE)
        {
            OVERLAPPED ovlCommPort = new OVERLAPPED();
            ;
            ReadFile(hComm, BufBytes, NumBytes, ref BytesRead, ref ovlCommPort);
            OutBytes = new byte\[BytesRead\];
            Array.Copy(BufBytes, OutBytes, BytesRead);
        }
        else
        {
            throw (new ApplicationException("串口未打开!"));
        }

        return OutBytes;
    }

    /// <summary>
    /// 写入字节到端口
    /// </summary>
    /// <param name="WriteBytes"></param>
    public void Write(byte\[\] WriteBytes)
    {
        if (hComm != INVALID\_HANDLE\_VALUE)
        {
            OVERLAPPED ovlCommPort = new OVERLAPPED();
            ;
            WriteFile(hComm, WriteBytes, WriteBytes.Length, ref BytesWritten, ref ovlCommPort);
        }
        else
        {
            throw (new ApplicationException("串口未打开!"));
        }
    }
}

#region 字符串和字节数组的转换
/// <summary>
/// 字符串和字节数组的转换
/// </summary>
class HexConverter
{
    //   hex string to byte and byte to hex string
    /// <summary>
    /// 把字节型转换成十六进制字符串
    /// </summary>
    /// <param name="InBytes"></param>
    /// <returns></returns>
    public static string ByteToString(byte\[\] InBytes)
    {
        return System.Text.Encoding.ASCII.GetString(InBytes);

        //string StringOut = "";
        //foreach (byte InByte in InBytes)
        //{
        //    StringOut = StringOut + String.Format("{0:X2} ", InByte);
        //}
        //return StringOut;
    }

    /// <summary>
    /// 把十六进制字符串转换成字节数组
    /// </summary>
    /// <param name="InString"></param>
    /// <returns></returns>
    public static byte\[\] StringToByte(string InString)
    {
        return System.Text.Encoding.ASCII.GetBytes(InString);

        //string\[\] ByteStrings;
        //ByteStrings = InString.Split(" ".ToCharArray());
        //byte\[\] ByteOut;
        //ByteOut = new byte\[ByteStrings.Length - 1\];
        //for (int i = 0; i == ByteStrings.Length - 1; i++)
        //{
        //    ByteOut\[i\] = Convert.ToByte(("0x" + ByteStrings\[i\]));
        //}
        //return ByteOut;
    }
}
#endregion

}

查看代码