使用的短信收发设备:单口串口短信收发设备 使用.NET短信包开发 读取短信是运行了一个Windows服务,7x24小时不间断循环。程序开发选择了基于AT命令的“.NET短信包”,包含的操作中我们需要用到的有:获取设备的连接状态、连接/关闭设备、发送\接收短信、读取错误信息。 1.检测连接状态,若重试N次后仍然无法连接则发送报告(通过邮件)并停止服务。 2.连接正常后读取短信内容,将字符串拆分,获取到所需字段,比如手机号,短信到达时间,短信内容等。 短信内容串规则(设备不同可能规则也不同)如下: 短信类型|存储位置|发送时间|接收号码|短信编码|短信长度|短信内容||短信类型|存储位置|发送时间|接收号码|短信编码|短信长度|短信内容。 多条短信以双竖线分隔,单条短信的多个字段以单竖线分隔,因为竖线可能会出现在短信内容中,所以不能以单竖线做为分隔符。我们通过单竖线的位置以及个数进行字段分解,最后代码如下:
// 记录竖线的个数 Int32 optPosition = 0;
// 存放竖线的索引 String[] optIndex = new String[6];
for (int i = 0; i < originalSMS.Length; i++) { if (optPosition == 6) { break; }
if (originalSMS[i] == '|') { optIndex[optPosition] = i.ToString(); optPosition++; } }
3.将内容写入数据库,释放设备连接。- 使用AT命令来监测设备 1.发送AT命令的方法 2.配置参数以及一些常用命令 完整源代码 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO.Ports;
namespace SMSRunState { public partial class Form1 : Form { public Form1() { InitializeComponent(); }
SerialPort port;
private void btnShow_Click(object sender, EventArgs e) { btnShow.Enabled = false; Random random = new Random(); progressBar.Value = random.Next(30, 80); port = new SerialPort(txtDevice.Text.Trim(), 9600, Parity.None, 8, StopBits.One);
port.ReadTimeout = 5000; port.WriteTimeout = 5000; port.RtsEnable = true;
Open(); txtResult.Text = CheckRunStatus(); Close(); progressBar.Value = 100; btnShow.Enabled = true; }
/// /// 监测运行状态 /// /// public String CheckRunStatus() { String device = ""; SendCommand("AT" + Environment.NewLine, ref device, 1);
StringBuilder sb = new StringBuilder();
if (!device.ToUpper().Contains("OK")) { // 如果处于发送状态则强制结束 port.Write(String.Empty); port.Write("AT" + Environment.NewLine);
//return "设备未找到,可能是电源未连接"; return device; } else { // 获取SIM信息,用来判断SIM是否正常,返回结果示例:AT+CCID +CCID: "898600" OK,分别表示89:国内,86中国,00中国移动/01中国联通 String sim = String.Empty; SendCommand("AT+CCID" + Environment.NewLine, ref sim, 5000); sb.Append(sim.Replace(Environment.NewLine, String.Empty) + Environment.NewLine);
// 获取信号强度,强度范围在0~31之间,返回结果示例:AT+CSQ +CSQ: 25,0 OK,分别表示25:信号强度 String signl = String.Empty; SendCommand("AT+CSQ" + Environment.NewLine, ref signl, 5000); sb.Append(signl.Replace(Environment.NewLine, String.Empty) + Environment.NewLine);
// 检测短信存储容量,返回结果示例:AT+CPMS="SM" +CPMS: 6,40,6,40 OK,分别表示6:已存短信数,40:SIM卡可存短信数 String capacity = String.Empty; SendCommand("AT+CPMS=\"SM\"" + Environment.NewLine, ref capacity, 5000); sb.Append(capacity.Replace(Environment.NewLine, String.Empty) + Environment.NewLine); }
return sb.ToString(); }
public void Open() { if (!port.IsOpen) { try { port.Open(); } catch (Exception ex) { throw ex; } } }
public void Close() { if (port.IsOpen) { try { port.Close(); } catch (Exception ex) { throw ex; } } }
/// 发送各种命令 /// /// 命令正文 /// 返回结果 /// 发送超时 /// 发送标识 private int SendCommand(string Sendcmd, ref string ReceiveData, int Overtime) { if (!port.IsOpen) { this.Open(); } if (port.IsOpen) { try { port.DiscardInBuffer(); //清空接收缓冲区 port.Write(Sendcmd); //写入命令 int num = 0, ret = 0; while (num++ < Overtime) { System.Threading.Thread.Sleep(1000); if (port.BytesToRead > 0) //存在需要读取的数据 { ret = port.BytesToRead; break; } else { System.Threading.Thread.Sleep(1); //延时1毫秒 等待数据发送到端口上 } }
if (ret > 0) //如果要读取的数据存在 读取数据 并且 打开接收 { ReceiveData = port.ReadExisting(); //先读取再激活接收事件 ReadExecting() }
return ret; } catch (Exception ex) { throw ex; } } return -1; }
/// /// 发送AT&F命令来恢复出厂设置,操作后返回"OK"字样 /// /// /// private void btnInit_Click(object sender, EventArgs e) { port = new SerialPort(txtDevice.Text.Trim(), 9600, Parity.None, 8, StopBits.One);
port.ReadTimeout = 5000; port.WriteTimeout = 5000; port.RtsEnable = true;
Open();
String result = String.Empty; SendCommand("AT&F" + Environment.NewLine, ref result, 5000); txtResult.Text = result;
Close(); } } }
- 常见问题判断 1.观察设备的电源/信号指示灯是否正常,并同时拨打设备的手机号是否能听到正常的嘟嘟声,如果出现已关机,一般是重新插拔一下电源再试试看。 2.使用上面写的小工具查看各项参数,比如卡内信息是否已满,有无信号等。 3.如果提示端口号和波段不正确,但确实没问题时,使用上面写的工具里的AT&F命令恢复出厂设置试试看。 前两天出现发送完短信后没有接收到回执报告的问题,检查了一圈后发现确实没什么问题,唯独没有拨打短信收发设备的手机号听听看,结果,听筒里传来一句优美的提示语:您拨打的电话已欠费停机,石化。 |