C#调用WM手机发送短信(源码)
一些系统,需要能够发送短信,量很小,平均每日10条。
运营商平台太贵,白名单很严格,小额只能发省内;
各短信平台有各种限制,大事件前后会关闭;
飞信以前可以用WAP发,但是现在多了验证码,搞不定了;
短信猫买来还得写控制程序,价钱和时间上……
手上有两部废弃的WM手机,没有故障,只是老旧不好用!
有一个WM软件(后面有下载),它在WM手机上开启一个Http服务器,使得我们可以在PC上通过浏览器直接访问!
有收发短信的功能!
把手机WiFi性能跳到最大,关闭每x分钟限制自动关闭;软件设置自动开启服务,关闭“运行时防止休眠”(它设计上有BUG,这个会导致服务10分钟就关闭),拉到启动目录设为自动启动。
OK!就是它了,我们写个程序包装一下,伪造为Web操作收发短信!
主要代码如下:
View Code
using System; using System.Collections.Generic; using System.Globalization; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Web; using NewLife; using NewLife.Linq; using NewLife.Log; using NewLife.Web; namespace WMSms { /// <summary> 手机类 </summary> class Mobile : DisposeBase { #region 属性 private String _Address; /// <summary> 地址 </summary> public String Address { get { return _Address; } set { _Address = value; } } private Boolean _Logined; /// <summary> 是否已登录 </summary> public Boolean Logined { get { return _Logined; } set { _Logined = value; } } #endregion #region 构造 public Mobile(String address) { Address = address; } protected override void OnDispose( bool disposing) { base .OnDispose(disposing); if (client != null ) client.Dispose(); } #endregion #region 通讯基础 private WebClientX client; void EnsureClient() { if (client != null ) return ; client = new WebClientX( true , true ); client.Encoding = Encoding.UTF8; ServicePointManager.Expect100Continue = false ; } String Get(String url) { EnsureClient(); // return client.DownloadString(url); var bts = client.DownloadData(url); return Encoding.UTF8.GetString(bts); } String Post(String url, String data) { EnsureClient(); client.Headers[ " Referer " ] = url; client.Headers[ " Content-Type " ] = " application/x-www-form-urlencoded " ; // return client.UploadString(url, data); var bts = Encoding.UTF8.GetBytes(data); bts = client.UploadData(url, bts); return Encoding.UTF8.GetString(bts); } String Post(String url, IDictionary <String, Object> data) { if (data == null ) return Post(url, "" ); var sb = new StringBuilder(); foreach ( var item in data) { if (sb.Length > 0 ) sb.Append( " & " ); if (item.Value != null ) sb.AppendFormat( " {0}={1} " , item.Key, HttpUtility.UrlEncode( "" + item.Value)); else sb.AppendFormat( " {0}= " , item.Key); } return Post(url, sb.ToString()); } #endregion #region 方法 public Boolean Login(String pass) { if (Logined) return true ; var url = String.Format( " http://{0}/authent/?returnurl=%2Ffs%2F " , Address); var html = Get(url); url = String.Format( " http://{0}/authent/?returnurl=%2Ffs%2F " , Address); var dic = new Dictionary<String, Object> (); dic.Add( " user " , " Admin " ); dic.Add( " pwd " , pass); html = Post(url, dic); var rs = !html.IsNullOrWhiteSpace() && html.Contains( " form " ); Logined = rs; return rs; } public Boolean SendMessage(String number, String content) { var url = String.Format( " http://{0}/messaging/?page=newmessage " , Address); var dic = new Dictionary<String, Object> (); dic.Add( " RequestDeliveryReport " , " chk " ); dic.Add( " recipient " , number); dic.Add( " recipientName " , null ); dic.Add( " smsbody " , content); var html = Post(url, dic); return !html.IsNullOrWhiteSpace() && html.Contains( " 已发信息 " ); } public Boolean Ping() { if (!Logined) return false ; try { var url = String.Format( " http://{0}/fs/ " , Address); var html = Get(url); if (html.IsNullOrWhiteSpace()) return false ; // 如果回到登录页面,则标记为未登录 if (html.Contains( " authent " )) { Logined = false ; return false ; } return html.Contains( " My Device " ); } catch (Exception ex) { XTrace.WriteException(ex); return false ; } } #endregion #region 接收短信 public List<Message> ReceiveUnReaded() { var list = Receive( 0 ); if (list == null ) return null ; list = list.Where(m => ! m.Readed).ToList(); var i = 1 ; var ls = list; while (ls.Count >= 10 && !ls[ls.Count - 1 ].Readed) { ls = Receive(i++ ); if (ls == null || ls.Count < 1 ) break ; ls = ls.Where(m => ! m.Readed).ToList(); list.AddRange(ls); if (list.Count >= 100 ) break ; } return list; } public List<Message> ReceiveFromTime(DateTime start) { var list = Receive( 0 ); if (list == null ) return null ; list = list.Where(m => m.Time > start).ToList(); var i = 1 ; var ls = list; while (ls.Count >= 10 && ls[ls.Count - 1 ].Time > start) { ls = Receive(i++ ); if (ls == null || ls.Count < 1 ) break ; ls = ls.Where(m => m.Time > start).ToList(); list.AddRange(ls); if (list.Count >= 100 ) break ; } return list; } static Regex _regMsg = new Regex( " <div class=\"([^\"]*)\"><span class=\"msgDesc\">从 :</span>\\s*([^<]*?)\\s*-\\s*<a href=\"\\?page=newmessage&recipient=([^&\"]*)[^\"]*\">答复</a><br/><span class=\"msgDesc\">已收到 :</span>\\s*([^<]*?)\\s*<br/>\\s*([^<]*?)\\s*</div> " , RegexOptions.IgnoreCase | RegexOptions.Compiled); public List<Message> Receive(Int32 page) { if (!Logined) return null ; var url = String.Format( " http://{0}/messaging/ " , Address); if (page > 1 ) url += " ?page= " + page; var html = Get(url); if (html.IsNullOrWhiteSpace()) return null ; var list = new List<Message> (); foreach (Match m in _regMsg.Matches(html)) { var msg = new Message(); msg.Readed = " readMsg " .EqualIgnoreCase(m.Groups[ 1 ].Value); // 名字 var name = m.Groups[ 2 ].Value.Trim(); if (! name.IsNullOrWhiteSpace()) { name = HttpUtility.HtmlDecode(name); var p = name.IndexOf( " ( " ); if (p > 0 ) name = name.Substring( 0 , p).Trim(); msg.Name = name; } // 号码 var num = m.Groups[ 3 ].Value.Trim(); if (! num.IsNullOrWhiteSpace()) { num = HttpUtility.UrlDecode(num); if (num.StartsWith( " +86 " )) num = num.Substring( 3 ); msg.Number = num; } // 时间 var dt = m.Groups[ 4 ].Value.Trim(); if (! dt.IsNullOrWhiteSpace()) { dt = HttpUtility.HtmlDecode(dt); var p = dt.IndexOf( " ( " ); if (p > 0 ) dt = dt.Substring( 0 , p).Trim(); DateTime d; if (DateTime.TryParse(dt, out d)) msg.Time = d; else if (DateTime.TryParseExact(dt, " MM/dd/yy dddd HH:mm:ss " , null , DateTimeStyles.None, out d)) msg.Time = d; } // 内容 var txt = m.Groups[ 5 ].Value.Trim(); if (! txt.IsNullOrWhiteSpace()) { msg.Content = HttpUtility.HtmlDecode(txt); } list.Add(msg); } return list; } public class Message { private String _Number; /// <summary> 号码 </summary> public String Number { get { return _Number; } set { _Number = value; } } private String _Name; /// <summary> 名称 </summary> public String Name { get { return _Name; } set { _Name = value; } } private String _Content; /// <summary> 内容 </summary> public String Content { get { return _Content; } set { _Content = value; } } private DateTime _Time; /// <summary> 时间 </summary> public DateTime Time { get { return _Time; } set { _Time = value; } } private Boolean _Readed; /// <summary> 是否已读 </summary> public Boolean Readed { get { return _Readed; } set { _Readed = value; } } } #endregion } }
刚下去小店买了一张移动动感地带的卡,50块办卡返50,分5月返还每月10元,套餐每月20元包400条短信,实际上,后面每个月只需要交10元即可!
配置一下路由器,把WM手机的Http端口映射到公网,可供远程应用系统直接调用!
现在很多可用的二手WM手机只需要一百多块钱即可买到。
这个方案跟短信猫不相上下,(短信猫成品三百多块),也算是多一种选择吧!
WM软件: WiFi.rar
源代码: WMSmsSrc.rar
我不相信神话,我只相信汗水!我不相信命运,我只相信双手!
作者: Leo_wl
出处: http://www.cnblogs.com/Leo_wl/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
版权信息查看更多关于C#调用WM手机发送短信(源码)的详细内容...