短信猫软件的实现(C#)<一>熟悉串口

GSM Modem俗称“短信猫”,PC可通过串口与其通信,通过向其所连接的串口发送AT指令控制我们的“猫”发送短信

写这样一个软件,首先要了解串口通信,.NET已经为我们封装了SerialPort类,方便串口通信。为了熟悉此串口类,我简单实现了一个串口调试器。

运行效果:

image

主要源代码:

简单串口调试器代码。
  1. using System;
  2. using System.Drawing;
  3. using System.IO.Ports;
  4. using System.Runtime.InteropServices;
  5. using System.Text;
  6. using System.Windows.Forms;
  7. namespace 串口调试器
  8. {
  9.     public partial class Form1 : Form
  10.     {
  11.         //hotkeyWinapi声明:
  12.         [DllImport("user32.dll")]
  13.         [return: MarshalAs(UnmanagedType.Bool)]
  14.         public static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
  15.         [DllImport("user32.dll")]
  16.         [return: MarshalAs(UnmanagedType.Bool)]
  17.         public static extern bool UnregisterHotKey(IntPtr hWnd, int id);
  18.         
  19.         SerialPort sp = new SerialPort();       //声明串口类
  20.         bool stoptb2 = false;
  21.         //发送字节计数
  22.         int fscout = 0;
  23.         //接收字节计数
  24.         int jscout = 0;
  25.         //十六进制显示标志
  26.         bool ishex = false;
  27.         //委托
  28.         delegate void HandleInterfaceUpdateDelegate(string text);  //委托,此为重点
  29.         HandleInterfaceUpdateDelegate interfaceUpdateHandle = null;
  30.         public Form1()
  31.         {
  32.             InitializeComponent();
  33.         }
  34.         //重载函数
  35.         protected override void WndProc(ref Message m)
  36.         {
  37.             //
  38.             const int WM_HOTKEY = 0x0312;
  39.             if (m.Msg == WM_HOTKEY)
  40.             {
  41.                 int id = m.WParam.ToInt32();
  42.                 //Ctrl+Z
  43.                 Byte[] byte1 = new Byte[1];
  44.                 byte1[0] = 0x1A;
  45.                 if (id == 100)
  46.                 {
  47.                     if (sp.IsOpen == true)
  48.                     {
  49.                         sp.Write(byte1, 0, 1);
  50.                     }
  51.                 }
  52.             }
  53.             base.WndProc(ref m);
  54.         }
  55.         private void Form1_Load(object sender, EventArgs e)
  56.         {
  57.             //初始化状态栏
  58.             toolStripStatusLabel1.Text = "串口调试器正在初始化    ";
  59.             //热键注册Ctrl+Alt+Z
  60.             RegisterHotKey(this.Handle, 100, 6, Convert.ToUInt32(Keys.Z));
  61.             //初始化combox1
  62.             foreach (string s in SerialPort.GetPortNames())
  63.             {
  64.                 comboBox1.Items.Add(s);
  65.             }
  66.             //初始化combox2
  67.             comboBox2.Items.Add("300");
  68.             comboBox2.Items.Add("600");
  69.             comboBox2.Items.Add("1200");
  70.             comboBox2.Items.Add("2400");
  71.             comboBox2.Items.Add("4800");
  72.             comboBox2.Items.Add("9600");
  73.             comboBox2.Items.Add("19200");
  74.             comboBox2.Items.Add("38400");
  75.             comboBox2.Items.Add("76800");
  76.             comboBox2.Items.Add("115200");
  77.             comboBox2.SelectedIndex = 5;
  78.             //初始化combox3
  79.             comboBox3.Items.Add("None");
  80.             comboBox3.Items.Add("Odd");
  81.             comboBox3.Items.Add("Even");
  82.             comboBox3.SelectedIndex = 0;
  83.             //初始化combox4
  84.             comboBox4.Items.Add("8");
  85.             comboBox4.Items.Add("7");
  86.             comboBox4.Items.Add("6");
  87.             comboBox4.SelectedIndex = 0;
  88.             //初始化combox5
  89.             comboBox5.Items.Add("1");
  90.             comboBox5.Items.Add("2");
  91.             comboBox5.SelectedIndex = 0;
  92.             //textbox1初始化
  93.             textBox1.Text = "1000";
  94.             //有串口
  95.             if (comboBox1.Items.Count > 0)
  96.             {
  97.                 comboBox1.SelectedIndex = 0;
  98.             
  99.                 //串口变量初始化
  100.                 sp.PortName = comboBox1.SelectedItem.ToString();
  101.                 sp.BaudRate = Convert.ToInt32(comboBox2.SelectedItem.ToString());
  102.                 sp.Parity = (Parity)Enum.Parse(typeof(Parity), comboBox3.SelectedItem.ToString());
  103.                 sp.DataBits = int.Parse(comboBox4.SelectedItem.ToString());
  104.                 sp.StopBits = (StopBits)Enum.Parse(typeof(StopBits), comboBox5.SelectedItem.ToString());
  105.                 sp.RtsEnable = true;
  106.                 sp.ReceivedBytesThreshold = 1;//设置 DataReceived 事件发生前内部输入缓冲区中的字节数
  107.                 sp.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.sp_DataReceived);    //DataReceived事件委托
  108.  
  109.             }
  110.             else
  111.             {
  112.                 label9.Text = "未检测到串口";
  113.                 label9.ForeColor = Color.Red;
  114.             }
  115.             //委托实例化
  116.             interfaceUpdateHandle = new HandleInterfaceUpdateDelegate(UpdateTextBox);  //实例化委托对象 
  117.  
  118.             //初始化状态栏
  119.             toolStripStatusLabel1.Text = "串口调试器初始化成功    ";
  120.         }
  121.         //委托的函数
  122.         private void UpdateTextBox(string text)
  123.         {
  124.             if (stoptb2 == false)
  125.             {
  126.                 textBox3.Text += text;
  127.             }
  128.             //更新接收显示
  129.             toolStripStatusLabel3.Text = String.Format(" 接收:{0} 字节    ", jscout);
  130.         }
  131.         //DataReceived事件委托方法
  132.         private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
  133.         {
  134.             int readlen = sp.BytesToRead;
  135.             //接收计数
  136.             jscout += readlen;
  137.             byte[] readBuffer = new byte[sp.ReadBufferSize];
  138.             sp.Read(readBuffer, 0, readBuffer.Length);
  139.             if (ishex)
  140.             {
  141.                 string readbuf = null;
  142.                 //十六进制格式化数据
  143.                 for(int i=0;i<readlen;i++)
  144.                 {
  145.                     string s = String.Format("{0:X}", Convert.ToInt32(readBuffer[i]));
  146.                     if (s.Length > 1)
  147.                     {
  148.                         readbuf += s+" ";
  149.                     }
  150.                     else
  151.                     {
  152.                         readbuf += "0" + s + " ";
  153.                     }
  154.                 }
  155.                 
  156.                 this.Invoke(interfaceUpdateHandle, readbuf);
  157.                     
  158.             }
  159.             else
  160.             {
  161.             
  162.                 
  163.                 this.Invoke(interfaceUpdateHandle, new string[] { Encoding.UTF8.GetString(readBuffer) });
  164.                 
  165.             }
  166.             
  167.         }
  168.         private void button1_Click(object sender, EventArgs e)
  169.         {
  170.             if (sp.IsOpen == false)
  171.             {
  172.                 try
  173.                 {
  174.                     sp.Open();
  175.                     //清空缓冲区
  176.                     sp.DiscardInBuffer();
  177.                     sp.DiscardOutBuffer();
  178.                 }
  179.                 catch (Exception)
  180.                 {
  181.                     label9.Text = "串口无法连接";
  182.                     return;
  183.                 }
  184.                     button1.Text = "断开串口";
  185.                     label6.Text = "已连接";
  186.                     label6.ForeColor = Color.Green;
  187.                     label9.Text = sp.PortName + "," + sp.BaudRate + "," + sp.Parity + "," + sp.DataBits + "," + sp.StopBits;
  188.                     //改变状态栏
  189.                     toolStripStatusLabel1.Text = "  " + label9.Text + "   ";
  190.                 
  191.             }
  192.             else
  193.             {
  194.                 if (checkBox2.Checked)
  195.                 {
  196.                     MessageBox.Show("正在发送,请先停止自动发送");
  197.                     return;
  198.                 }
  199.                 sp.Close();
  200.                 label6.Text = "已断开";
  201.                 label6.ForeColor = Color.Red;
  202.                 label9.Text = " 串口关闭状态";
  203.                 button1.Text = "连接串口";
  204.                 //改变状态栏
  205.                 toolStripStatusLabel1.Text = "串口关闭状态 不能操作串口";
  206.             }
  207.         }
  208.         private void button2_Click(object sender, EventArgs e)
  209.         {
  210.             if (stoptb2 == false)       //停止显示标志置位
  211.             {
  212.                 stoptb2 = true;
  213.                 button2.Text = "继续显示";
  214.             }
  215.             else
  216.             {
  217.                 stoptb2 = false;                    //停止显示标志复位
  218.                 button2.Text = "停止显示";
  219.             }
  220.         }
  221.         private void button3_Click(object sender, EventArgs e)
  222.         {
  223.             textBox3.Text = "";
  224.         }
  225.         private void button4_Click(object sender, EventArgs e)
  226.         {
  227.             if (sp.IsOpen == true)
  228.             {
  229.                 fscout += textBox2.Text.Length;
  230.                 sp.Write(textBox2.Text);
  231.                 toolStripStatusLabel2.Text = String.Format("  发送:{0} 字节    ", fscout);
  232.             }
  233.             else
  234.             {
  235.                 MessageBox.Show("串口未打开");
  236.             }
  237.         }
  238.         private void button5_Click(object sender, EventArgs e)
  239.         {
  240.             fscout = 0;
  241.             toolStripStatusLabel2.Text = "  发送:0 字节    ";
  242.         }
  243.         private void button6_Click(object sender, EventArgs e)
  244.         {
  245.             jscout = 0;
  246.             toolStripStatusLabel3.Text = " 接收:0 字节    ";
  247.         }
  248.         private void button7_Click(object sender, EventArgs e)
  249.         {
  250.             About abFrm = new About();
  251.             abFrm.Owner = this;
  252.             abFrm.ShowDialog();
  253.         }
  254.         //程序退出
  255.         private void button8_Click(object sender, EventArgs e)
  256.         {
  257.             UnregisterHotKey(this.Handle, 100);
  258.             sp.Close();
  259.             this.Close();
  260.         }
  261.         //combox1改变
  262.         private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
  263.         {
  264.             if (sp.IsOpen == false)
  265.             {
  266.                 sp.PortName = comboBox1.SelectedItem.ToString();
  267.             }
  268.         }
  269.         //combox2改变
  270.         private void comboBox2_SelectedIndexChanged(object sender, EventArgs e)
  271.         {
  272.             sp.BaudRate = Convert.ToInt32(comboBox2.SelectedItem.ToString());
  273.         }
  274.         //combox3改变
  275.         private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
  276.         {
  277.             sp.Parity = (Parity)Enum.Parse(typeof(Parity), comboBox3.SelectedItem.ToString());
  278.         }
  279.         //combox4改变
  280.         private void comboBox4_SelectedIndexChanged(object sender, EventArgs e)
  281.         {
  282.             sp.DataBits = int.Parse(comboBox4.SelectedItem.ToString());
  283.         }
  284.         //combox5改变
  285.         private void comboBox5_SelectedIndexChanged(object sender, EventArgs e)
  286.         {
  287.             sp.StopBits = (StopBits)Enum.Parse(typeof(StopBits), comboBox5.SelectedItem.ToString());
  288.         }
  289.         private void checkBox1_CheckedChanged(object sender, EventArgs e)
  290.         {
  291.             if (checkBox1.Checked)
  292.             {
  293.                 ishex = true;
  294.             }
  295.             else
  296.             {
  297.                 ishex = false;
  298.             }
  299.         }
  300.         private void timer1_Tick(object sender, EventArgs e)
  301.         {
  302.             if (sp.IsOpen == true)
  303.             {
  304.                 fscout += textBox2.Text.Length;
  305.                 sp.Write(textBox2.Text);
  306.                 toolStripStatusLabel2.Text = String.Format("  发送:{0} 字节    ", fscout);
  307.             }
  308.             else
  309.             {
  310.                 MessageBox.Show("串口未打开");
  311.             }
  312.         }
  313.         private void checkBox2_CheckedChanged(object sender, EventArgs e)
  314.         {
  315.             if (sp.IsOpen == false)
  316.             {
  317.                 checkBox2.Checked = false;
  318.             }
  319.             else
  320.             {
  321.                 timer1.Enabled = checkBox2.Checked;
  322.             }
  323.             
  324.         }
  325.         private void textBox1_TextChanged(object sender, EventArgs e)
  326.         {
  327.             if (textBox1.Text == null||textBox1.Text=="")
  328.             {
  329.                 timer1.Interval = 1000;
  330.             }
  331.             else
  332.             {
  333.                 timer1.Interval = Convert.ToInt32(textBox1.Text);
  334.             }
  335.         }
  336.         private void checkBox2_Click(object sender, EventArgs e)
  337.         {
  338.             if (sp.IsOpen == false)
  339.             {
  340.                 MessageBox.Show("串口未连接");
  341.             }
  342.         }
  343.     }
  344. }

作为C#新手的我第一次完成一个比较完整的程序

不足之处欢迎大家拍砖

附件:工程项目文件

转载于:https://www.cnblogs.com/Engin/archive/2010/11/03/1868365.html

短信:又称GSM MODEM,GSM,无线短信模块,GSM模块,短信设备。根据集成模块的个数不同,又分为单池两种。 短信是什么?短信其实是种支持GSM无线通讯的工业级调制解调器,般基于法国WAVECOM或德国SIEMENS(西门子)GSM模块,插入国内移动通信运营商的SIM卡后即可接入运营商GSM网络,实现无线GSM通话、短信、数据等功能。与手机相比,实际上核心模块致,只是手机多了屏幕、键盘以及软件界面支持,而短信是在PC上通过串口通讯用AT指令去控制的,但两者能完成的短信收发功能是完全相同的。 随着手机及短信的普及,越来越多的行业开始发展企业短信应用,短信设备凭借其低成本、稳定可靠的点对点通信、方便快捷接入的优势已经成为企业短信领域重要的短信接入方式之。中德福林依托其强大的研发实力、多年的无线通信经验,推出了系列短信产品,除了原装正版的WAVECOM GSM MODEM,自身更是研发了多种型号的短信设备,基本上基于WAVECOM核心模块,接口包括串口(RS232)、USB接口、PCI接口、网口等,并提供系列短信开发包及示例程序,支持VC/VC++/VB/DELPHI/PB/C#/.NET/ASP/JAVA/JSP二次开发。 短信设备二次开发接口 基于短信开发行业短信应用,软件开发商可以采取以下三种方式: 直接使用AT指令:基于串口通讯模式使用AT指令直接操作短信,这是最底层的短信开发模式,但是我们建议客户尽量不采用此方法,因为这种方式需要对短信的AT指令及特性非常熟悉短信二次开发包:短信厂商针对软件开发商短信应用提供的二次开发包,其底层是基于短信的AT指令,对于软件开发商只需要调用二次开发包或者控件中的API即可。基于多年的开发经验,为客户提供套基于动态链接库(DLL)技术的短信开发包,可以支持所有的 WINDOWS 环境下开发工具,也提供支持 JAVA 开发的 JAR 包。 短信通信中间件:这是我们独家提供的基于数据库接口的短信通信服务器软件软件开发商只需要提交短信队列到数据库里即可,开发简单快速,节约人力成本,是最佳的短信应用开发接口模式。 短信的优势 基于短信建立行业短信应用,具有如下优势: 投入低:无需购置接入服务器,只需购置经济的短信设备; 安装维护方便:短信设备容易安装,维护手段简便易用; 安全性好:服务采用自服方式,不需经第三方,信息保密,整个应用都在企业的控制之内; 用户覆盖面广:该服务能通过不同运营商的短信中心发送或接收短信息,兼容移动、联通的所有手机用户以及电信、网通的所有小灵通用户; 可靠性高:采用点对点的发送方式,优先级别高,稳定性好; 系统容量可扩展:通过简单添加通信模块就可以扩充系统容量; 业务开展自由:业务内容不受运营商限制,可以根据企业的具体需求进行业务和应用的定制; 接入门槛低:无需和运营商、服务提供商进行繁琐的商务谈判,只需短信就可以迅速构建企业自己的短信服务系统。 短 信 直 销 网 产 品 简 介 欢迎由此查看本网短信产品规范及技术指标 短信般也叫做GSM MODEM,从英文名翻译过来,其实就是支持GSM制式通讯的调制解调器。所以,短信还有很多别称,如GSM,无线短信模块,GSM短信模块等。因为大部分客户都是拿着GSM MODEM去收发短信,也就是在行业应用市场上,GSM MODEM最大的用途是用来收发短信,因此,大多数人还是称之为短信短信是什么?短信其实是种支持GSM无线通讯的工业级调制解调器,般基于法国WAVECOM或德国SIEMENS(西门子)GSM模块,插入国内移动通信运营商的SIM卡后即可接入运营商GSM网络,实现无线GSM通话、短信、数据等功能。 短信(GSM MODEM)的核心模块实际上就是手机的核心模块。当短信接通电源以后,GSM MODEM的内置软件就开始工作,如果您插入了某个移动运营商的SIM卡,GSM MODEM便完全就和手机样接入到移动通信网络中去了。与此同时,计算机可以通过串口或USB连接GSM MODEM,通过套AT指令,便可以操作GSM MODEM,例如收发短信。其实也可以拨打电话、收发传真等等,只是我们般没有必要使用这些多余功能。因此短信(GSM MODEM)与手机的最大区别在于手机自带屏幕、键盘、应用软件,而短信相当于个处于黑箱操作的手机,需要计算机去驱动和控制。 短信(GSM MODEM)的分类:按照与计算机的不同接口,短信可分为串口短信、USB接口短信、PCI接口短信、网口短信等。按照模块数的多少,短信可分为单口短信短信池两种。短信池其实就是将多个模块集成到起通过多串口或者网口与计算机形成多串口通讯,从而实现多个模块并发的设备。按照无线网络制式的不同,又可分为GSM短信、CDMA短信和小灵通短信短信开发接口(GSM MODEM SDK),基于短信开发行业短信应用,软件开发商可以采取以下四种方式:1、直接使用AT指令,基于串口通讯模式使用AT指令直接操作短信,这是最底层的短信开发模式,基本上无论是哪种接口的短信,其实质还是通过GSM MODEM的串口通讯AT指令来驱动的。2、短信开发包:短信厂商针对软件开发商短信应用提供的二次开发包,其底层是基于短信的AT指令,对于软件开发商只需要调用二次开发包或者控件中的API即可。3、短信通信中间件:这是套的基于数据库接口的短信通信软件,用户只需提交短信队列到数据库即可进行短信收发。因此无论您用的是哪种开发语言,只要您能读写数据库即可。这种开发简单快速,节约人力成本,是最快捷的短信应用开发模式。4、直接使用由第三方提供的短信网关:这时其实已经没有必要再购买短信了(因为短信网关公司已经替您配备了类似设备),用户只需按照网关说明直接调用短信网关接口,系统就会自动实现短信收发。短信网关公司的网址为:SmsGate.CN。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值