C# 通过短信猫(使用深圳市仕方通信的4G短信报警模块)实现的一个短信网关,可实时收短信并根据短信内容调用指定的接口实现联动其它系统或者写入数据库
实现步骤:
1、下载我的资源里的相应类库DLL。
2、下载Log4jnet.dll,方便日志记录。
先看一下效果:
3、直接看代码,如下:
Program.cs
using GSMMODEM;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Web.Script.Serialization;
using LOG;
using System.Text.RegularExpressions;
using System.Collections;
namespace GSM_LTE_MODEM
{
class Program
{
//delegate void SmsReceive;
static GsmModem gm;
static Dictionary<string, object> config;
static void Main(string[] args)
{
gm = new GsmModem();
listen();
//send("153****1260","TEST");
while (true)
{
Thread.Sleep(500);
}
}
#region 发送短信
static void send(string phone,string sms)
{
try
{
gm.SendMsg(phone, sms);
Console.WriteLine("发送成功");
}
catch
{
Console.WriteLine("发送失败");
return;
}
}
#endregion
#region 监听接收短信
static void listen()
{
try
{
config = load_config();
Log.info("配置加载成功");
}
catch
{
Log.info("配置加载失败");
return;
}
gm.ComPort = "COM1";
gm.BaudRate = 115200;
gm.AutoDelMsg = true;
gm.Open();
gm.SmsRecieved += gm_SmsRecieved;
if (gm.IsOpen)
{
Log.info("串口连接成功");
}
else
{
Log.error("串口设备未连接");
}
}
#endregion
#region 新消息处理事件
static void gm_SmsRecieved(object sender, EventArgs e)
{
Log.info("有新的消息");
if (gm.IsOpen)
{
try
{
DecodedMessage dm = gm.ReadNewMsg();
Log.info(string.Format("手机号码[{0}]\t短信内容[{1}]\t发送时间[{2}]" ,dm.PhoneNumber, dm.SmsContent, dm.SendTime.ToString()));
try
{
dispose(dm.PhoneNumber, dm.SmsContent);
Log.info("消息处理成功");
}
catch
{
Log.error("消息处理失败");
}
}
catch
{
Log.error("消息读取失败");
return;
}
}
else
{
Log.error("串口关闭,读取消息失败");
}
}
#endregion
#region 新消息处理
static void dispose(string phone,string sms)
{
sms = sms.Trim().Replace("\0","");
phone = phone.Trim();
object[] obj = (object[])config["service"];
foreach (Dictionary<string, object> o in obj)
{
string pattern = o["regex"].ToString();
string url = o["url"].ToString();
if (Regex.IsMatch(sms, pattern))
{
sms = System.Web.HttpUtility.UrlEncode(sms, System.Text.Encoding.UTF8);
string req = string.Format("destnationNo={0}&mobile={1}&content={2}{3}", "15657191916_4g", phone, sms, o["requisition"].ToString());
try
{
string ret = HTTPRequest.post(url,req);
if (ret.Contains("fail"))
{
Log.error("调用接口" + url + ",失败!");
}
else
{
Log.info("调用接口" + url + ",成功!");
}
}
catch (Exception e)
{
Log.error("调用接口" + url + ",失败!");
}
}
}
}
#endregion
#region 加载配置
static Dictionary<String, object> load_config()
{
StreamReader sr = new StreamReader("config.ini");
string json = sr.ReadToEnd();
JavaScriptSerializer java = new JavaScriptSerializer();
Dictionary<String, object> o = (Dictionary<String, object>)java.DeserializeObject(json);
sr.Close();
return o;
}
#endregion
}
}
Log.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using log4net;
using System.Reflection;
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
namespace LOG
{
class Log
{
public static void info(string message){
//string filename = System.DateTime.Now.Year +"_"+ System.DateTime.Now.Month+"_"+ System.DateTime.Now.Day;
//string filepath = "logs"+filename+".txt";
//System.IO.StreamWriter write = new System.IO.StreamWriter(filepath, true);
//write.WriteLine(System.DateTime.Now.ToString() + ":"+message);
//write.Close();
ILog log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
//记录错误日志
//log.Error("error", new Exception("发生了一个异常"));
//记录严重错误
//log.Fatal("fatal", new Exception("发生了一个致命错误"));
//记录一般信息
log.Info(message);
//记录调试信息
//log.Debug("debug");
//记录警告信息
//log.Warn("warn");
}
public static void error(string message)
{
//string filename = System.DateTime.Now.Year +"_"+ System.DateTime.Now.Month+"_"+ System.DateTime.Now.Day;
//string filepath = "logs"+filename+".txt";
//System.IO.StreamWriter write = new System.IO.StreamWriter(filepath, true);
//write.WriteLine(System.DateTime.Now.ToString() + ":"+message);
//write.Close();
ILog log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
//记录错误日志
log.Error(message);
//记录严重错误
//log.Fatal("fatal", new Exception("发生了一个致命错误"));
//记录一般信息
//log.Info("info");
//记录调试信息
//log.Debug("debug");
//记录警告信息
//log.Warn("warn");
}
}
}
HTTPRequest.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace GSM_LTE_MODEM
{
class HTTPRequest
{
/// <summary>
/// 公共请求方法
/// </summary>
/// <param name="requestUrl">请求的URL</param>
/// <param name="requestStr">需要传的参数</param>
/// <returns></returns>
public static string post(string requestUrl, string requestStr)
{
WebRequest request = WebRequest.Create(requestUrl);//创建请求
request.Method = "POST"; //请求方式
request.ContentType = "application/x-www-form-urlencoded"; //请求类型
//将参数转换为二进制流
byte[] requestBytes = Encoding.Default.GetBytes(requestStr);
request.ContentLength = requestBytes.Length;
Stream requestStream = request.GetRequestStream();
requestStream.Write(requestBytes, 0, requestBytes.Length);
requestStream.Close();
string result = "";
try
{
WebResponse response = request.GetResponse(); //创建相应并接收相应
Stream ReceiveStream = response.GetResponseStream(); //创建接收流
StreamReader sr = new StreamReader(ReceiveStream, Encoding.UTF8);
result = sr.ReadToEnd();
sr.Close();
}
catch (Exception)
{
result = "fail";
}
return result;
}
public static string get(string url)
{
WebRequest request = WebRequest.Create(url);//创建请求
request.Method = "GET"; //请求方式
request.ContentType = "text/html;charset=UTF-8"; //请求类型
string result = "";
try
{
WebResponse response = request.GetResponse(); //创建相应并接收相应
Stream ReceiveStream = response.GetResponseStream(); //创建接收流
StreamReader sr = new StreamReader(ReceiveStream, Encoding.UTF8);
result = sr.ReadToEnd();
sr.Close();
}
catch (Exception)
{
result = "fail";
}
return result;
}
}
}
配置文件config.ini
{"id":1,"service":[{"regex":"\\w+","url":"http://*******:****/update","requisition":""}]}
程序配置文件App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<log4net>
<!-- 将日志输出到控制台 -->
<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level - %message%newline"/>
</layout>
</appender>
<!-- 按日期切分日志文件,并将日期作为日志文件的名字 -->
<appender name="RollingFileAppenderNameByDate" type="log4net.Appender.RollingFileAppender">
<!-- 日志文件存放位置,可以为绝对路径也可以为相对路径 -->
<file value="Logs/"/>
<!-- 将日志信息追加到已有的日志文件中-->
<appendToFile value="true"/>
<!-- 最小锁定模式,以允许多个进程可以写入同一个文件 -->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock"/>
<!-- 指定按日期切分日志文件 -->
<rollingStyle value="Date"/>
<!-- 日志文件的命名规则 -->
<datePattern value=""Logs_"yyyyMMdd".log""/>
<!-- 当将日期作为日志文件的名字时,必须将staticLogFileName的值设置为false -->
<staticLogFileName value="false"/>
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level - %message%newline"/>
</layout>
</appender>
<root>
<!--控制级别,由低到高:ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF
比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录
如果没有定义LEVEL的值,则缺省为DEBUG-->
<level value="ALL"/>
<!--将日志输出到控制台-->
<appender-ref ref="ConsoleAppender"/>
<!--将日志写到文件中
<appender-ref ref="FileAppender" />
按文件大小切分日志文件
<appender-ref ref="RollingFileAppenderBySize" />
按日期切分日志文件-->
<!--<appender-ref ref="RollingFileAppenderByDate" />
按日期切分日志文件,并将日期作为日志文件的名字-->
<appender-ref ref="RollingFileAppenderNameByDate"/>
<!--既按大小又按日期切分日志文件-->
<!--<appender-ref ref="RollingFileAppenderBySizeAndDate" />-->
<!--将日志利用ADO.NET记录到数据库中
<appender-ref ref="AdoNetAppender_SQLServer" />-->
</root>
</log4net>
</configuration>