利用139,189,yahoo等邮箱短信提示来免费发短信提示

综合现在能查到的免费短信发送方式,在飞信今年未升级前,大多是利用分析出的飞信客户端协议来发送短信,

优点是速度快,使用简单!

后来由于飞信协议的升级,以及验证码问题,大多的此类发送方式已经挂掉了,

网上也有关于利用google日历来变相进行短信发送的方法,

还有就是利用139邮箱,实际上不仅仅是139邮箱,189,yahoo等很多邮箱服务商都提供短信通知功能!

 

今天在首页又看到一篇文章利用139邮箱来进行短消息发送,随后自己测试了下189邮箱,下面将封装一个类来实现此功能

 

首先,在用smtp 发信测试的时候,发现 139,189等邮箱的smtp服务器不兼容.net smtp类的邮件发送,但是outlook等一些软件可以正常使用

 

关于.net smtpclient类不能发送139,189邮件服务器的问题也有人抓包分析了,是因为这2个邮件服务器对于一个命令解析的不兼容,在此不多说了!有兴趣可以google查下!

 

言规正传,既然这种变相的短信发送方式,是利用邮件服务商提供的一个新邮件短信提示功能,那么就是说我的支持短信提示的邮箱只要收到信邮件,就会由邮件服务商向

 

我们事先设置的手机发送新邮件提示, 139,189邮箱非别是移动和电信的手机邮箱,所以默认是跟手机账号关联的,yahoo邮箱则可以自行设置手机账号,具体的邮箱接收短信

 

的设置需要根据邮箱支持的功能自行设定,这里不多解释了,贴下189的短信提示设置:

 

 

 清楚了上面这层原理,那我们就直接来写代码了,这里说明下:为了简化操作,这里使用。net smtpclient来发信,

 

所以配置smtp发送的时候不支持的是无法使用的,其实配置一般的支持smtp发送邮件的就行,我会给出用QQ邮箱发信的测试用例! 

 

以下简单的封装,通过SmtpClient来给能够进行短信提示的邮箱发送新邮件,已达到变相短信提示目的!

  public class SmsAPI : IDisposable

    {
        
#region  fields
        
///   <summary>
        
///  System.Net.Mail.SmtpClient对象
        
///   </summary>
         static  SmtpClient _smtp;
        SmtpConfig _config;
        
///   <summary>
        
///  是否已释放过资源
        
///   </summary>
         bool  disponsed  =   false ;
        
///   <summary>
        
///  异步发送完成事件
        
///   </summary>
         event  EventHandler < SendInfo >  _event;
        
///   <summary>
        
///  
        
///   </summary>
         object  objectLock  =   new  Object();
        
#endregion
#region  delegates/events
        
///   <summary>
        
///  异步发送完后触发的事件
        
///   </summary>
         public   event  EventHandler < SendInfo >  SendCompleted
        {
            add
            {
                
lock  (objectLock)
                {
                    _event 
+=  value;
                }
            }
            remove
            {
                
lock  (objectLock)
                {
                    _event 
-=  value;
                }
            }
        }
#endregion
        
#region  methods
        
///   <summary>
        
///  构造函数
        
///   </summary>
        
///   <param name="xmlpath"> Smtp的xml配置文件 </param>
         public  SmsAPI( string  xmlpath)
        {
            
if  ( ! File.Exists(xmlpath))
                
throw   new  FileNotFoundException( " error:not found configxml file " );
            
using  (FileStream fs  =   new  FileStream(xmlpath, FileMode.Open, FileAccess.Read))
            {
                XmlSerializer xs 
=   new  XmlSerializer( typeof (SmtpConfig));
                _config 
=  xs.Deserialize(fs)  as  SmtpConfig;
                InitSmtp(_config.Host, _config.Port, _config.Sll, _config.User, _config.Password); 
/* 初始化SMTPCLIENT对象 */
                fs.Close();
            }

        }
        
///   <summary>
        
///  构造函数
        
///   </summary>
        
///   <param name="host"> SMTP服务器 </param>
        
///   <param name="user"> SMTP用户名 </param>
        
///   <param name="password"> SMTP密码 </param>
         public  SmsAPI( string  host,  string  user,  string  password)
            : 
this (host,  25 false , user, password)
        {

        }
        
///   <summary>
        
///  构造函数
        
///   </summary>
        
///   <param name="host"> SMTP服务器 </param>
        
///   <param name="port"> SMTP端口 </param>
        
///   <param name="ssl"> 是否使用SLL </param>
        
///   <param name="user"> SMTP用户名 </param>
        
///   <param name="password"> SMTP密码 </param>
         public  SmsAPI( string  host,  int  port,  bool  ssl,  string  user,  string  password)
        {
            InitSmtp(host, port, ssl, user, password);   
/* 初始化SMTPCLIENT对象 */

        }
        
///   <summary>
        
///  初始化SMTP对象
        
///   </summary>
        
///   <param name="host"> SMTP服务器 </param>
        
///   <param name="port"> SMTP端口 </param>
        
///   <param name="ssl"> 是否使用SLL </param>
        
///   <param name="user"> SMTP用户名 </param>
        
///   <param name="password"> SMTP密码 </param>
         private   void  InitSmtp( string  host,  int  port,  bool  ssl,  string  user,  string  password)
        {
            
if  (host  ==   null   ||  host.Length  ==   0 )
                
throw   new  ArgumentNullException( " error:host is null " );
            
if  (port  <   0   ||  port  >   65534 )
                
throw   new  ArgumentException( " error:port (0~65534) " );
            _smtp 
=   new  SmtpClient();
            _smtp.SendCompleted 
+=   new  SendCompletedEventHandler(SendCompletedProc); // 设置SmtpClient对象的SendCompleted事件
            _smtp.Host  =  host;
            _smtp.Port 
=  port;
            _smtp.EnableSsl 
=  ssl;
            _smtp.Credentials 
=   new  NetworkCredential(user, password);

            _config 
=   new  SmtpConfig(host, port, ssl, user, password); // 实例一个SmtpConfig对象
        }
        
///   <summary>
        
///  SmtpClient.SendCompleted 事件的绑定函数
        
///   </summary>
        
///   <param name="sender"></param>
        
///   <param name="e"></param>
         void  SendCompletedProc( object  sender,AsyncCompletedEventArgs e)
        {
            SendInfo info 
=  e.UserState  as  SendInfo;
            info.Ex 
=  e.Error; // 这里设置info对象的Ex属性
             if (_event != null )
                _event(
null , info);  // 事件投递给上层调用
        }
        
///   <summary>
        
///  实现IDisponse接口Disponse方法
        
///   </summary>
         public   void  Dispose()
        {
            Disponse(
true );
            GC.SuppressFinalize(
this );
        }
        
///   <summary>
        
///  资源释放
        
///   </summary>
        
///   <param name="disponseing"></param>
         protected   virtual   void  Disponse( bool  disponseing)
        {
            
if  ( ! disponsed)
            {
                
if  (disponseing)
                {
                    
// 释放受控资源
                    _smtp  =   null ;
                    _config 
=   null ;
                }
                
// 释放非受控资源
            }
            disponsed 
=   true ;
        }
        
///   <summary>
        
///  发送邮件
        
///   </summary>
        
///   <param name="_mail"> 邮件对象 </param>
         public   void  Send(MailMessage _mail)
        {
            
try
            {   
                _smtp.SendAsync(_mail, 
new  SendInfo(_mail.To[ 0 ].ToString(), DateTime.Now, null ));
            }
            
catch  (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        
///   <summary>
        
///  发送邮件
        
///   </summary>
        
///   <param name="from"> 发件人 </param>
        
///   <param name="to"><收件人/param>
        
///   <param name="subject"> 主题 </param>
        
///   <param name="body"> 正文 </param>
         public   void  Send( string  from,  string  to,  string  subject,  string  body)
        {
            
try
            {

                MailMessage _mail 
=   new  MailMessage();
                _mail.From 
=   new  MailAddress(from);
                _mail.To.Add(
new  MailAddress(to));
                _mail.Subject 
=  subject;
                _mail.IsBodyHtml 
=   true ;
                _mail.Body 
=  body;
                _smtp.SendAsync(_mail, 
new  SendInfo(to, DateTime.Now, null ));
            }
            
catch  (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

        }
        
///   <summary>
        
///  get appdomain base directory
        
///   </summary>
        
///   <returns></returns>
         public   static   string  AppDirectory()
        {
            
return  AppDomain.CurrentDomain.BaseDirectory;
        }
        
///   <summary>
        
///  XML序列化SmtpConfig对象
        
///   </summary>
        
///   <param name="fileName"> 文件名 </param>
         public   void  SaveConfig( string  fileName)
        {
            
if  (fileName  ==   null   ||  fileName.Length  ==   0 )
                fileName 
=   " smsapi.xml " ;
            
string  xmlpath  =  Path.Combine(AppDirectory(), fileName);
            
using (StreamWriter sw = new  StreamWriter(xmlpath, false ,System.Text.Encoding.Default))
            {
                XmlSerializer xs 
=   new  XmlSerializer( typeof (SmtpConfig));
                xs.Serialize(sw, _config);
                sw.Close();
            }
        }
        
#endregion

    }
    
///   <summary>
    
///  发送信息
    
///   </summary>
     public   class  SendInfo:System.EventArgs
    {
        
public  SendInfo( string  _to, DateTime _time,Exception _ex)
        {
            
this .To  =  _to;
            
this .Time  =  _time;
            
this .Ex  =  _ex;
        }
        
///   <summary>
        
///  接收用户
        
///   </summary>
         public   string  To
        {
            
get ;
            
set ;
        }
        
///   <summary>
        
///  发送时间
        
///   </summary>
         public  DateTime Time
        {
            
get ;
            
set ;
        }
        
///   <summary>
        
///  发送产生的异常
        
///   </summary>
         public  Exception Ex
        { 
           
get ;
           
set ;
        }
    }

 

 

 

ExpandedBlockStart.gif SmtpConfig
 [Serializable]
    
public   class  SmtpConfig
    {
        
public  SmtpConfig()
        { 
        }
        
///   <summary>
        
///  构造函数
        
///   </summary>
        
///   <param name="host"> SMTP服务器 </param>
        
///   <param name="port"> SMTP端口 </param>
        
///   <param name="ssl"> 是否启用SSL </param>
        
///   <param name="user"> 用户名 </param>
        
///   <param name="password"> 密码 </param>
         public  SmtpConfig( string  host, int  port, bool  ssl, string  user, string  password)
        {
            
this .Host  =  host;
            
this .Port  =  port;
            
this .Sll  =  ssl;
            
this .User  =  user;
            
this .Password  =  password;
        }
        
string  _host  =   "" ;
        
///   <summary>
        
///  SMTP服务器
        
///   </summary>
         public   string  Host
        {
            
get { return  _host;}
            
set
            {
                
if  (value  ==   null   ||  value.Length  ==   0 )
                    
throw   new  ArgumentNullException( " error:host is null " );
                _host 
=  value;
            }
        }
        
int  _port  =   25 ;
        
///   <summary>
        
///  SMTP端口
        
///   </summary>
         public   int  Port
        {
            
get  {  return  _port; }
            
set
            {
                
if  (value  <   0   ||  value  >   65534 )
                    
throw   new  ArgumentException( " error:port (0~65534) " );
                _port 
=  value;
            }
        }
        
///   <summary>
        
///  是否启用SSL
        
///   </summary>
         public   bool  Sll
        {
            
get ;
            
set ;
        }
        
///   <summary>
        
///  用户名
        
///   </summary>
         public   string  User
        {
            
get ;
            
set ;
        }
        
///   <summary>
        
///  用户密码
        
///   </summary>
         public   string  Password
        {
            
get ;
            
set ;
        }
    }

 

 

 

上面是封装的SmsApi 代码,很简单,大家都能看的懂,下面贴下示例代码,然后我根据示例代码稍微解释下

 

SmsAPI api  =   new  SmsAPI( " smtp.qq.com " " 发送账号 " " 发送账号的密码 " );
            {
                api.SendCompleted 
+=   new  EventHandler < SendInfo > ((obj, e)  =>
                {
                    Console.WriteLine(
" to:{0}  time={1} " , e.To, e.Time);
                    
if  (e.Ex  !=   null )//如果发送出了异常,是在事件的绑定函数里可以体现出来的,
                    {
                        Console.WriteLine(
" exception:{0} " , e.Ex);
                    }
                    
                });
                api.SaveConfig(
" sms.xml " ); //xml序列化保存Smtp配置
                api.Send(
" ****@qq.com " " 1533651****@189.cn " " 测试邮件 " " 这是一封测试邮件 " );

            }

 

 

 需要解释的有3部分,

1,对象的创建:重载了3个构造函数,分别需要传递的参数在代码中写的很明白, 大家可以看下,

    在构造参数传递后进行 SmtpClient对象的初始化

2,发送邮件: 重载了2个函数,都是最简单的邮件发送,也是。net SmtpClient 最基本的操作,但是这里使用了异步操作,这样做的原因下一点说

3, 邮件发送完成的事件:这里是在SmsApi类自定义一个事件SendCompleted,当SmtpClient对象异步发送邮件后触发给上层调用的,这样我们上层调用的时候只管发送邮件,最后发    送成功还是发送异常都可以在事件绑定的方法里反映出来

 

 

以上代码经测试,完全OK, 只是189邮箱的短信提示稍有延迟! 接下来有时间,在试试其他邮箱,写的比较不自信,如有问题 希望大家多指教!

转载于:https://www.cnblogs.com/cxwx/archive/2010/09/01/1814786.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值