群发软件开发过程

37 篇文章 0 订阅
13 篇文章 0 订阅
border="0" src="http://forum.booye.com/byhtm/1.html" frameborder="0" width="470" height="60">

  以前我们公司是有网上的群发软件,每天每次都发有上十万份电子日刊,但是根据用户回应,以及公司内部推测,
得到群发软件效果不好,发送成功率很低;又由于公司内部特殊需求,公司决定自己开发。
  前些日子,经理让我开发一个群发软件,当时我很软松的接下啦,因为以前研究过类似问题,也做过单发软件邮件
功能,用的是微软自带的邮件发送类库(System.Web.Mail)MailMessage、SmtpMail两个类
(初期过程:http://blog.csdn.net/mlks_2008/archive/2007/04/22/1574864.aspx),想心把这个单发做成模块或类库
不就可以了吗,又没有什么大问题。回去就把SMTP服务装上了,程序很快就搞定了,发送邮件时报错,
捕获的异常信息是“未能访问"CDO.Message"对象”,到时网上查了一下,原因是我的WIN2003系统没有cdonts.dll,在WIN2000
找了一个此文件,在DOS窗口内,进入System32目录下,执行regsvr32 cdonts.dll 注册了一下,发送成功了.之后传到
服务器上,公司人员用它发送,公司的邮箱、163邮件都可以收到邮件;用了大半个月后发现hotmail.com、163.com邮箱
有时能收到,有时收不到,只有公司邮箱正常.查了几天也不知道是什么原因。只好另换其它,之后找了三个类库(Jmail类,
web service,编写的类库),而且当前使用的方法比.net自带的类库更好,有发送成功失败返回值(有时不能返回与机子安全性
配制有关,要开放一些端口,禁用邮件收发限制等)。
  目前邮件发送还有一个问题,就是hotmail.com等邮箱把邮件识别为垃圾邮件,正在研究中,待以后补充...

内容简写不少,有兴趣的可以与我联系。一起讨论 QQ:67222474 MSN:mlks_2008@hotmail.com

目前使用的发送类库: 

 


/*  **********************************************
 * Rainsoft Development Library for Microsoft.NET
 * 
 * Copyright (c) 2004,2005 RainTrail Studio.China
 * All Rigths Reserved!
 * Author: Q.yuhen (qyuhen@hotmail.com)
 ********************************************** 
*/  
using  System;
using  System.Text;
using  System.Text.RegularExpressions;
using  System.IO;
using  System.Collections;
using  System.Net;
using  System.Net.Sockets;
using  Rainsoft.Text;

namespace  Rainsoft.Network
{
    
#region  Message

    
///   <summary>
    
///  正文格式
    
///   </summary>
     public   enum  EMailFormat 
    { 
        
///   <summary>
        
///  文本
        
///   </summary>
        Text, 
        
///   <summary>
        
///  HTML
        
///   </summary>
        Html 
    }

    
///   <summary>
    
///  优先级
    
///   </summary>
     public   enum  EMailPriority 
    { 
        
///   <summary>
        
///  普通
        
///   </summary>
        Normal, 
        
///   <summary>
        
///  低
        
///   </summary>
        Low,
        
///   <summary>
        
///  高
        
///   </summary>
        High 
    }

    
///   <summary>
    
///  邮件消息构造类
    
///   </summary>
     public   class  EMailMessage
    {
        
private   string  partRoot  =   " =====000_ROOT===== " ;
        
private   string  partSon  =   " =====001_SON===== " ;
        
private   string  partGrandSon  =   " =====002_GRANDSON===== " ;
        
private   string  partStart  =   " --{0} " ;
        
private   string  partEnd  =   " --{0}-- " ;
        
private   string  CRLF  =   " " ;
        
private   string  conTransEncoding  =   " Content-Transfer-Encoding: base64 " ;
        
private   string  body  =   "" ;
        
private   string  cc  =   "" ;
        
private   string  from  =   "" ;
        
private   string  subject  =   "" ;
        
private   string  to  =   "" ;
        
private   string  charset  =   " GB2312 " ;
        
private   string  htmlBaseUrl  =   "" ;
        
private  EMailPriority priority  =  EMailPriority.Normal;
        
private  EMailFormat bodyFormat  =  EMailFormat.Text;
        
private  ArrayList attachments  =   new  ArrayList();
        
private  ArrayList images  =   new  ArrayList();

        
///   <summary>
        
///  附件
        
///   </summary>
         public  ArrayList Attachments
        {
            
get  {  return  attachments; }
        }

        
///   <summary>
        
///  正文
        
///   </summary>
         public   string  Body
        {
            
get  {  return  body; }
            
set  { body  =  value; }
        }

        
///   <summary>
        
///  正文类型
        
///   </summary>
         public  EMailFormat BodyFormat
        {
            
get  {  return  bodyFormat; }
            
set  { bodyFormat  =  value; }
        }

        
///   <summary>
        
///  抄送
        
///   </summary>
         public   string  Cc
        {
            
get  {  return  cc; }
            
set  { cc  =  value; }
        }

        
///   <summary>
        
///  发信人
        
///   </summary>
         public   string  From
        {
            
get  {  return  from; }
            
set  { from  =  value; }
        }

        
///   <summary>
        
///  优先级
        
///   </summary>
         public  EMailPriority Priority
        {
            
get  {  return  priority; }
            
set  { priority  =  value; }
        }

        
///   <summary>
        
///  标题
        
///   </summary>
         public   string  Subject
        {
            
get  {  return  subject; }
            
set  { subject  =  value; }
        }

        
///   <summary>
        
///  收信人
        
///   </summary>
         public   string  To
        {
            
get  {  return  to; }
            
set  { to  =  value; }
        }

        
///   <summary>
        
///  字符集
        
///   </summary>
         public   string  Charset
        {
            
get  {  return  charset; }
            
set  { charset  =  value; }
        }

        
///   <summary>
        
///  HTML 邮件图片的基地址
        
///   </summary>
         public   string  HtmlBaseUrl
        {
            
get  {  return  htmlBaseUrl; }
            
set  { htmlBaseUrl  =  value; }
        }
                    
        
///   <summary>
        
///  对邮件进行编码
        
///   </summary>
        
///   <returns></returns>
         public   string  Encode()
        {
            
string  htmlText  =   " Html Mail " ;
            
string  conTypeRelat  =   " Content-Type: multipart/related; " ;
            
string  conTypeText  =   " Content-Type: text/plain; " ;
            
string  conTypeAlter  =   " Content-Type: multipart/alternative; " ;
            
string  conTypeHtml  =   " Content-Type: text/html; " ;
            
string  conTypeMixed  =   " Content-Type: multipart/mixed; " ;
            
string  mimeMessage  =   " This is a multi-part message in MIME format. "  ;
            
string  typeAlter  =   " type=multipart/alternative " ;
            
string  charsetx  =   " charset="{0}" " ;
            
string  boundary  =   " boundary="{0}" " ;

            
try
            {
                StringBuilder temp 
=   new  StringBuilder();

                
//  HEAD -----------------------------------------------------------
        
                
//  from
                temp.Append( string .Format( " From:{0}  " , from));
                temp.Append(CRLF);

                
//  to
                 string [] tos  =  to.Split( new   char [] { ' ; ' });
                temp.Append(
" To:  " );
                
for int  i = 0 ; i <  tos.Length; i ++ )
                {
                    temp.Append( i 
>   0   ?   " , "  :  ""  );
                    temp.Append(tos[i]);
                }
                temp.Append(CRLF);

                
//  cc
                 if (cc  !=   null )
                {
                    tos
=  cc.Split( new   char [] { ' ; ' });
                    temp.Append(
" Cc:  " );
                    
for int  i = 0 ; i <  tos.Length; i ++ )
                    {
                        temp.Append( i 
>   0   ?   " , "  :  ""  );
                        temp.Append(tos[i]);
                    }
                    temp.Append(CRLF);
                }

                
//  date
                temp.Append( string .Format( " Date: {0} " , DateTime.Now.ToString( " r " )));
                temp.Append(CRLF);

                
//  subject
                temp.Append( string .Format( " Subject: =?{0}?B?{1}?= " , charset, Base64.String(subject)));
                temp.Append(CRLF);

                
//  mime version
                temp.Append( " MIME-Version: 1.0 " );
                temp.Append(CRLF);

                
//  priority
                temp.Append( string .Format( " X-Priority: {0} " , ( int )priority));
                temp.Append(CRLF);

                
//  x-mailer
                temp.Append( " X-Mailer: Rainsoft Mail Sender. " );
                temp.Append(CRLF);

                
//  CONTENT -------------------------------------------

                
//  content
                 if  (attachments.Count  ==   0 )
                {
                    
if  (bodyFormat  ==  EMailFormat.Text)
                    {
                        temp.Append(conTypeText);
                        temp.Append(CRLF);
                        temp.Append(
string .Format(charsetx, charset));
                        temp.Append(CRLF);
                        temp.Append(conTransEncoding);
                        temp.Append(CRLF);
                        temp.Append(CRLF);

                        
//  text body
                        temp.Append(Base64.String(body));
                        temp.Append(CRLF);
                    }
                    
else
                    {
                        temp.Append(conTypeRelat);
                        temp.Append(CRLF);
                        temp.Append(
string .Format(boundary, partRoot));
                        temp.Append(CRLF);
                        temp.Append(typeAlter);
                        temp.Append(CRLF);
                        temp.Append(CRLF);
                        temp.Append(mimeMessage);
                        temp.Append(CRLF);
                        temp.Append(CRLF);

                        
//  root start
                        temp.Append( string .Format(partStart, partRoot));
                        temp.Append(CRLF);
                        temp.Append(conTypeAlter);
                        temp.Append(CRLF);
                        temp.Append(
string .Format(boundary, partSon));
                        temp.Append(CRLF);
                        temp.Append(CRLF);

                        
//  text body
                        temp.Append( string .Format(partStart, partSon));
                        temp.Append(CRLF);
                        temp.Append(conTypeText);
                        temp.Append(CRLF);
                        temp.Append(
string .Format(charsetx, charset));
                        temp.Append(CRLF);
                        temp.Append(conTransEncoding);
                        temp.Append(CRLF);
                        temp.Append(CRLF);
                        temp.Append(Base64.String(htmlText));
                        temp.Append(CRLF);
                        temp.Append(CRLF);

                        
//  html body
                        temp.Append( string .Format(partStart, partSon));
                        temp.Append(CRLF);
                        temp.Append(conTypeHtml);
                        temp.Append(CRLF);
                        temp.Append(
string .Format(charsetx, charset));
                        temp.Append(CRLF);
                        temp.Append(conTransEncoding);
                        temp.Append(CRLF);
                        temp.Append(CRLF);
                        encodeHtmlBody(temp);
                        temp.Append(CRLF);
                        temp.Append(CRLF);

                        
//  son end
                        temp.Append( string .Format(partEnd, partSon));
                        temp.Append(CRLF);
                        temp.Append(CRLF);

                        
//  html images
                        encodeImages(temp);
                    }
                }
                
else
                {
                    
if  (bodyFormat  ==  EMailFormat.Text)
                    {
                        
//  root start
                        temp.Append(conTypeMixed );
                        temp.Append(CRLF);
                        temp.Append(
string .Format(boundary, partRoot));
                        temp.Append(CRLF);
                        temp.Append(CRLF);
                        temp.Append(mimeMessage);
                        temp.Append(CRLF);
                        temp.Append(CRLF);

                        
//  text body
                        temp.Append( string .Format(partStart, partRoot));
                        temp.Append(CRLF);
                        temp.Append(conTypeText);
                        temp.Append(CRLF);
                        temp.Append(
string .Format(charsetx, charset));
                        temp.Append(CRLF);
                        temp.Append(conTransEncoding);
                        temp.Append(CRLF);
                        temp.Append(CRLF);
                        temp.Append(Base64.String(body));
                        temp.Append(CRLF);
                        temp.Append(CRLF);
                    }
                    
else
                    {
                        temp.Append(conTypeMixed);
                        temp.Append(CRLF);
                        temp.Append(
string .Format(boundary, partRoot));
                        temp.Append(CRLF);
                        temp.Append(CRLF);
                        temp.Append(mimeMessage);
                        temp.Append(CRLF);
                        temp.Append(CRLF);

                        
//  root start
                        temp.Append( string .Format(partStart, partRoot));
                        temp.Append(CRLF);
                        temp.Append(conTypeRelat);
                        temp.Append(CRLF);
                        temp.Append(
string .Format(boundary, partSon));
                        temp.Append(CRLF);
                        temp.Append(typeAlter);
                        temp.Append(CRLF);
                        temp.Append(CRLF);

                        
//  son start
                        temp.Append( string .Format(partStart, partSon));
                        temp.Append(CRLF);
                        temp.Append(conTypeAlter);
                        temp.Append(CRLF);
                        temp.Append(
string .Format(boundary, partGrandSon));
                        temp.Append(CRLF);
                        temp.Append(CRLF);

                        
//  text body
                        temp.Append( string .Format(partStart, partGrandSon));
                        temp.Append(CRLF);
                        temp.Append(conTypeText);
                        temp.Append(CRLF);
                        temp.Append(
string .Format(charsetx, charset));
                        temp.Append(CRLF);
                        temp.Append(conTransEncoding);
                        temp.Append(CRLF);
                        temp.Append(CRLF);
                        temp.Append(Base64.String(htmlText));
                        temp.Append(CRLF);
                        temp.Append(CRLF);

                        
//  html body
                        temp.Append( string .Format(partStart, partGrandSon));
                        temp.Append(CRLF);
                        temp.Append(conTypeHtml);
                        temp.Append(CRLF);
                        temp.Append(
string .Format(charsetx, charset));
                        temp.Append(CRLF);
                        temp.Append(conTransEncoding);
                        temp.Append(CRLF);
                        temp.Append(CRLF);
                        encodeHtmlBody(temp);
                        temp.Append(CRLF);
                        temp.Append(CRLF);

                        
//  grandson end
                        temp.Append( string .Format(partEnd, partGrandSon));
                        temp.Append(CRLF);
                        temp.Append(CRLF);

                        
//  html images
                        encodeImages(temp);

                        
//  son end
                        temp.Append( string .Format(partEnd, partSon));
                        temp.Append(CRLF);
                        temp.Append(CRLF);
                    }
                }

                
//  attchments
                encodeAttachments(temp);

                temp.Append(
string .Format(partEnd, partRoot));
                temp.Append(CRLF);

                
return  temp.ToString();
            }
            
catch
            {
                
return   "" ;
            }
        }

        
///   <summary>
        
///  导入 HTML 文件到正文
        
///   </summary>
         public   void  ImportHtmlFile( string  file)
        {
            
if  (File.Exists(file))
            {
                StreamReader r 
=   new  StreamReader(file, Encoding.Default);
                body 
=  r.ReadToEnd();
                htmlBaseUrl 
=  Path.GetDirectoryName(file);
                bodyFormat 
=  EMailFormat.Html;
            }
        }

        
///   <summary>
        
///  对 HTML 正文进行编码。
        
///   </summary>
        
///   <param name="temp"></param>
         private   void  encodeHtmlBody(StringBuilder temp)
        {
            
//  搜索全部图像连接
             string  p  =   " (?<a1>/<img.*?)(src ?= ?["'])(?<url>.*?)(["'])(?<a2>.*?/>) " ;
            
string  s  =  Regex.Replace(body, p,  new  MatchEvaluator(matchEvaluator), RegexOptions.IgnoreCase  |  RegexOptions.Singleline);

            p 
=   " background ?= ?["'](?<url>.*?)["'] " ;
            s 
=  Regex.Replace(s, p,  new  MatchEvaluator(matchEvaluator), RegexOptions.IgnoreCase  |  RegexOptions.Singleline);

            temp.Append(Base64.String(s));
        }

        
///   <summary>
        
///  Regex 回调函数。提取图片文件列表。
        
///   </summary>
         private   string  matchEvaluator(Match match)
        {
            
string  file  =  match.Groups[ " url " ].Value.ToLower();

            
//  还原正确路径
             if  (file.StartsWith( " file:// " )) 
                file 
=  file.Substring( 7 );
            
else
                file 
=  Path.Combine(htmlBaseUrl, file.Replace( " / " @" " ));

            
//  添加到列表
             if  (File.Exists(file))
            {
                images.Add(file);

                
string  cid  =   " cid: "   +  getImageCid(file, images.Count  -   1 );  //  cid 不能大写
                 if  (match.Value.ToLower().StartsWith( " background " ))
                    
return   string .Format( " background="{0}" " , cid);
                
else
                    
return   string .Format( " {0}src="{1}"{2} " , match.Groups[ " a1 " ], cid, match.Groups[ " a2 " ]); 
            }
            
else
                
return  match.Value;
        }

        
///   <summary>
        
///  获取 HTML 邮件中图片的 CID
        
///   </summary>
        
///   <param name="file"> 图片文件名 </param>
        
///   <param name="index"> 在列表中的索引位置 </param>
        
///   <returns></returns>
         private   string  getImageCid( string  file,  int  index)
        {
            
//  _主文件名(索引).扩展名
             return   string .Format( " _{0}({1}){2} "
                Path.GetFileNameWithoutExtension(file).Replace(
"   " "" ),
                index,
                Path.GetExtension(file).Replace(
"   " "" ));
        }

        
///   <summary>
        
///  对 HTML 图像进行编码
        
///   </summary>
         private   void  encodeImages(StringBuilder temp)
        {
            
if  (bodyFormat  ==  EMailFormat.Html  &&  images.Count  >   0 )
            {
                
for ( int  i  =   0 ; i  <  images.Count; i ++ )
                {
                    
string  file  =  ( string )images[i];
                    
if  ( ! File.Exists(file))  continue ;

                    
if  (attachments.Count  ==   0 )
                    {
                        temp.Append(
string .Format(partStart, partRoot));
                        temp.Append(CRLF);
                    }
                    
else
                    {
                        temp.Append(
string .Format(partStart, partSon));
                        temp.Append(CRLF);
                    }

                    
string  type  =   "" ;
                    
switch  (Path.GetExtension(file))
                    {
                        
case   " .jpg " : type  =   " jpeg " break ;
                        
default : type  =  Path.GetExtension(file).Substring( 1 );  break ;
                    }
                    temp.Append(
string .Format( " Content-Type: image/{0}; " , type));
                    temp.Append(CRLF);
                    temp.Append(
string .Format( " name="{0}" " , Path.GetFileName(file)));
                    temp.Append(CRLF);
                    temp.Append(conTransEncoding);
                    temp.Append(CRLF);
                    temp.Append((
string .Format( " Content-ID: <{0}> " , getImageCid(file, i))));
                    temp.Append(CRLF);
                    temp.Append(CRLF);
                    temp.Append(Base64.File(file));
                    temp.Append(CRLF);        
                }
            }
        }

        
///   <summary>
        
///  对附件进行编码
        
///   </summary>
         private   void  encodeAttachments(StringBuilder temp)
        {
            
if  (attachments.Count  >   0 )
            {
                
foreach ( object  obj  in  attachments)
                {
                    FileInfo info 
=   new  FileInfo(( string )obj);
                    
if  (info.Exists)
                    {
                        temp.Append(
string .Format(partStart, partRoot));
                        temp.Append(CRLF);
                        temp.Append(
" Content-Type: application/octet-stream; " );
                        temp.Append(CRLF);
                        temp.Append(
string .Format( " name="{0}" " , info.Name));
                        temp.Append(CRLF);
                        temp.Append(conTransEncoding);
                        temp.Append(CRLF);
                        temp.Append(
" Content-Disposition: attachment; " );
                        temp.Append(CRLF);
                        temp.Append(
string .Format( " filename="{0}" " , info.Name));
                        temp.Append(CRLF);
                        temp.Append(CRLF);

                        temp.Append(Base64.File(info.FullName));
                        temp.Append(CRLF);
                    }
                }
            }
        }
    }
    
#endregion

    
#region  Smtp

    
///   <summary>
    
///  SMTP 邮件发送
    
///   </summary>
    
///   <remarks>
    
///   <para> 1. 支持身份验证。   </para>
    
///   <para> 2. 支持附件。 </para>
    
///   <para> 3. 支持无 SMTP 服务器的邮件直接投送功能。 </para>
    
///   <para> 4. 支持 HTML 邮件。 </para>
    
///   <para> 5. 支持 EMAIL 地址真实性验证功能。 </para>
    
///   </remarks>
    
///   <example>
    
///   <para> 1. 使用 Smtp Server 发送普通邮件 </para>
    
///  某些 Smtp Server (如:263.net) 要求发信人(From)地址必须是验证帐号的地址,
    
///  否则发送失败。
    
///   <code>
    
///  EMailSmtp smtp = new EMailSmtp();
    
///  smtp.SmtpServer = "smtp.263.net";
    
///  smtp.UserName = "username";
    
///  smtp.Password = "password";
    
///      
    
///  EMailMessage message = new EMailMessage();
    
///  message.To = "q.yuhen@263.net";
    
///  message.From = "someone@sina.com.cn";
    
///  message.Subject = "标题";
    
///  message.Body = "邮件测试!";
    
///  
    
///  message.Attachments.Add(@"c:winntmmdet.log");
    
///  message.Attachments.Add(@"c:winnthh.exe");
    
///  
    
///  smtp.Send(message);
    
///   </code>     
    
///  除了使用 EMailMessage 对象外,还可是使用另外一种简便模式发送
    
///   <code>
    
///  EMailSmtp smtp = new EMailSmtp();
    
///  smtp.SmtpServer = "smtp.263.net";
    
///  smtp.UserName = "username";
    
///  smtp.Password = "password";
    
///  smtp.Send("q.yuhen@263.net", "someone@sina.com.cn", "标题", "邮件测试");
    
///   </code>         
    
///   <para> 2. 直投将邮件发送到对方信箱中,无需 SMTP 服务器。 </para>
    
///  DNS 服务器地址属性设置可省略,但是为了提高速度,建议使用本地 DNS 服务器。
    
///  直接发送时,一些服务器(如:263.net)要求接收人和发送人地址不能相同,否则将失败。
    
///  而且,接收人不能包含多个地址,也就是说不能使用 ";" 来连接多个地址。
    
///   <code>
    
///  EMailSmtp smtp = new EMailSmtp();
    
///  smtp.DnsServer = "192.168.0.1";
    
///      
    
///  EMailMessage message = new EMailMessage();
    
///  message.To = "q.yuhen@263.net";
    
///  message.From = "someone@sina.com.cn";
    
///  message.Subject = "标题";
    
///  message.Body = "邮件测试!";
    
///  
    
///  message.Attachments.Add(@"c:winntmmdet.log");
    
///  message.Attachments.Add(@"c:winnthh.exe");
    
///  
    
///  smtp.SendEMS(message);
    
///   </code>         
    
///  同样也可以使用简便模式发送
    
///   <code>
    
///  EMailSmtp smtp = new EMailSmtp();
    
///  smtp.DnsServer = "192.168.0.1";  
    
///  smtp.SendEMS("q.yuhen@263.net", "someone@sina.com.cn", "标题", "邮件测试");
    
///   </code>     
    
///   <para> 3. HTML 邮件发送 </para>
    
///   <para> 由于 HTML 内部的图片可能使用相对路径,因此您必须指定 HtmlBaseUrl,也就是 HTML 文件所在路径。
    
///  同样支持直接投送和简便模式,请参考上面代码。 </para>
    
///   <code>
    
///  EMailSmtp smtp = new EMailSmtp();
    
///  smtp.SmtpServer = "smtp.263.net";
    
///  smtp.UserName = "username";
    
///  smtp.Password = "password";
    
///      
    
///  EMailMessage message = new EMailMessage();
    
///  message.To = "q.yuhen@263.net";
    
///  message.From = "someone@sina.com.cn";
    
///  message.Subject = "标题";
    
///  
    
///  message.Body = @"&lt;html&gt;&lt;font color='red'&gt;body&lt;/font&gt;&lt;br&gt;&lt;img src = '1.gif'&gt;&lt;/html&gt;";
    
///  message.HtmlBaseUrl = @"D:SystemMy DocumentsMy Pictures";
    
///  message.BodyFormat = EMailFormat.Html;
    
///  
    
///  message.Attachments.Add(@"c:winntmmdet.log");
    
///  message.Attachments.Add(@"c:winnthh.exe");
    
///  
    
///  smtp.Send(message);
    
///   </code>   
    
///   <para> 4. HTML 文件邮件发送 </para>
    
///   <para> 使用 ImportHtmlFile 将 HTML 文件导入到 EMailMessage 对象时,无需指定 HtmlBaseUrl 和 BodyFormat
    
///  属性。同样支持直接投送和简便模式,请参考上面代码。 </para>
    
///   <code>
    
///  EMailSmtp smtp = new EMailSmtp();
    
///  smtp.SmtpServer = "smtp.263.net";
    
///  smtp.UserName = "username";
    
///  smtp.Password = "password";
    
///      
    
///  EMailMessage message = new EMailMessage();
    
///  message.To = "q.yuhen@263.net";
    
///  message.From = "someone@sina.com.cn";
    
///  message.Subject = "标题";
    
///  
    
///  message.ImportHtmlFile(@"D:SystemMy DocumentsHomepage€3index.htm");
    
///  
    
///  message.Attachments.Add(@"c:winntmmdet.log");
    
///  message.Attachments.Add(@"c:winnthh.exe");
    
///  
    
///  smtp.Send(message);
    
///   </code>     
    
///   <para> 5. 验证 EMail 地址的真实性 </para>
    
///   <para>  部分邮件服务器对 RCPT TO 命令并不作验证,因此这个功能并不能保证 100% 正确。 </para>
    
///   <code>
    
///  EMailSmtp smtp = new EMailSmtp();
    
///  Console.WriteLine(smtp.EMailExists("q.yuhen@263.net"));
    
///   </code>
    
///   </example>
     public   sealed   class  EMailSmtp
    {
        
private   string  smtpServer  =   " localhost " ;
        
private   string  userName  =   "" ;
        
private   string  password  =   "" ;
        
private   string  dnsServer  =   "" ;

        
///   <summary>
        
///  构造函数
        
///   </summary>
         public  EMailSmtp()
        {
        }

        
///   <summary>
        
///  Smtp 服务器地址。
        
///   </summary>
         public   string  SmtpServer
        {
            
set  { smtpServer  =  value; }
            
get  {  return  smtpServer; }
        }

        
///   <summary>
        
///  Smtp 登录帐号。
        
///   </summary>
         public   string  UserName
        {
            
set  { userName  =  value; }
            
get  {  return  userName; }
        }

        
///   <summary>
        
///  Smtp 登录密码。
        
///   </summary>
         public   string  Password
        {
            
set  { password  =  value; }
            
get  {  return  password; }
        }

        
///   <summary>
        
///  域名解析服务器
        
///   </summary>
         public   string  DnsServer
        {
            
set  { dnsServer  =  value; }
            
get  {  return  dnsServer; }
        }

        
///   <summary>
        
///  发送邮件
        
///   </summary>
        
///   <param name="mailTo"> 接收人地址 </param>
        
///   <param name="mailFrom"> 发送人地址 </param>
        
///   <param name="subject"> 标题 </param>
        
///   <param name="bodyText"> 正文 </param>
        
///   <returns></returns>
         public   bool  Send( string  mailTo,  string  mailFrom,  string  subject,  string  bodyText)
        {
            EMailMessage mail 
=   new  EMailMessage();
            mail.From 
=  mailFrom;
            mail.To 
=  mailTo;
            mail.Subject 
=  subject;
            mail.Body 
=  bodyText;
            mail.BodyFormat 
=  EMailFormat.Text;

            
return   this .Send(mail);
        }

        
///   <summary>
        
///  EMS 方式发送邮件
        
///   </summary>
         public   bool  SendEMS( string  mailTo,  string  mailFrom,  string  subject,  string  bodyText)
        {
            EMailMessage mail 
=   new  EMailMessage();
            mail.From 
=  mailFrom;
            mail.To 
=  mailTo;
            mail.Subject 
=  subject;
            mail.Body 
=  bodyText;
            mail.BodyFormat 
=  EMailFormat.Text;

            
return   this .SendEMS(mail);
        }

        
///   <summary>
        
///  获取 MX 记录
        
///   </summary>
         private  MXRecord[] getMX( string  email)
        {
            
try
            {
                
string  host  =  email.Substring(email.IndexOf( " @ " +   1 );

                DnsMX mx 
=   new  DnsMX();

                
if  (dnsServer  !=   string .Empty)  mx.AddDnsServer(dnsServer);
                mx.AddDnsServer(
new   string []{ " 202.102.192.68 " });  //  添加辅助地址,防止用户输入的错误。

                MXRecord[] list 
=  mx.GetMXRecords(host);
                
if  (list.Length  ==   0
                {
                    list 
=   new  MXRecord[ 1 ];
                    list[
0 ].Exchange  =  host;
                }

                
return  list;
            }
            
catch
            {
            }
            
return   null ;
        }

        
///   <summary>
        
///  EMS 方式发送邮件
        
///   </summary>
         public   bool  SendEMS(EMailMessage message)
        {
            
try
            {
                
int  i  =  message.To.IndexOf( " ; " );
                
if  (i  >   - 1 ) message.To  =  message.To.Substring( 0 , i);

                MXRecord[] list 
=  getMX(message.To);

                
foreach (MXRecord r  in  list)
                {
                    
this .smtpServer  =  r.Exchange;
                    
this .userName  =   "" ;
                    
this .password  =   "" ;
                    
if  ( this .Send(message))  return   true ;
                }
            }
            
catch
            {
            }
            
return   false ;
        }

        
///   <summary>
        
///  发送邮件。
        
///   </summary>
        
///   <param name="message"> 邮件内容对象。 </param>
        
///   <returns> 是否发送成功。 </returns>
         public   bool  Send(EMailMessage message)
        {
            
return   this .smtp(message,  false );
        }

        
///   <summary>
        
///  验证邮箱地址是否真实存在。
        
///   </summary>
        
///   <param name="email"> 邮件地址 </param>
        
///   <returns></returns>
         public   bool  EMailExists( string  email)
        {
            EMailMessage message 
=   new  EMailMessage();
            message.From 
=   " test@sina.com.cn " ;
            message.To 
=  email;

            MXRecord[] list 
=  getMX(message.To);
            
foreach (MXRecord r  in  list)
            {
                
this .smtpServer  =  r.Exchange;
                
this .userName  =   "" ;
                
this .password  =   "" ;
                
if  ( this .smtp(message,  true ))  return   true ;
            }
            
return   false ;
        }

        
///   <summary>
        
///  邮件发送 AND 地址验证
        
///   </summary>
        
///   <param name="message"> 邮件内容对象。 </param>
        
///   <param name="checkEMail"> 是否验证地址。 </param>
        
///   <returns></returns>
         private   bool  smtp(EMailMessage message,  bool  checkEMail)
        {
            
try
            {
                IPHostEntry IPhst 
=  Dns.Resolve(smtpServer);
                IPEndPoint endPt 
=   new  IPEndPoint(IPhst.AddressList[ 0 ],  25 );
                Socket sock 
=   new  Socket(endPt.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

                
//  Connect to Smtp Server
                sock.Connect(endPt);
                
if ( ! checkResponse(sock,  220 ))
                { 
                    sock.Close();
                    
return   false ;
                }

                
if (userName  !=   "" )
                {
                    
//  ESMTP HELO
                    sendData(sock,  string .Format( " EHLO {0} " , Dns.GetHostName() ));
                    
if ( ! checkResponse(sock,  250 ))
                    {
                        sock.Close();
                        
return   false ;
                    }

                    
//  AUTH LOGIN
                    sendData(sock,  string .Format( " AUTH LOGIN " ));
                    
if ( ! checkResponse(sock,  334 ))
                    {
                        sock.Close();
                        
return   false ;
                    }

                    
//  USERNAME
                    sendData(sock,  string .Format( " {0} " ,Base64.String(userName)));
                    
if ( ! checkResponse(sock,  334 ))
                    {
                        sock.Close();
                        
return   false ;
                    }

                    
//  PASSWORD
                    sendData(sock,  string .Format( " {0} " ,Base64.String(password)));
                    
if ( ! checkResponse(sock,  235 ))
                    {
                        sock.Close();
                        
return   false ;
                    }
                }
                
else
                {
                    
//  SMTP HELO
                    sendData(sock,  string .Format( " HELO {0} " , Dns.GetHostName() ));
                    
if ( ! checkResponse(sock,  250 ))
                    {
                        sock.Close();
                        
return   false ;
                    }
                }

                
//  MAIL FROM
                sendData(sock,  string .Format( " MAIL From:{0} " , message.From));
                
if ( ! checkResponse(sock,  250 ))
                {
                    sock.Close();
                    
return   false ;
                }

                
//  RCPT TO
                 string [] tos  =  message.To.Split( new   char [] { ' ; ' });
                
foreach  ( string  to  in  tos)
                {
                    sendData(sock, 
string .Format( " RCPT TO:<{0}> " , to));
                    
if ( ! checkResponse(sock,  250 ))
                    { 
                        sock.Close();
                        
return   false ;
                    }
                    
else
                    {
                        
//  验证 EMail 地址是否存在。
                         if  (checkEMail)
                        {
                            
//  QUIT
                            sendData(sock,  " QUIT " );
                            checkResponse(sock, 
221 );
                            sock.Close(); 
                            
return   true ;
                        }
                    }
                }

                
//  CC
                 if (message.Cc  !=   "" )
                {
                    tos 
=  message.Cc.Split( new   char [] { ' ; ' });
                    
foreach  ( string  To  in  tos)
                    {
                        sendData(sock, 
string .Format( " RCPT TO:<{0}> " , To));
                        
if ( ! checkResponse(sock,  250 ))
                        { 
                            sock.Close();
                            
return   false ;
                        }
                    }
                }

                
//  DATA
                sendData(sock, ( " DATA " ));
                
if ( ! checkResponse(sock,  354 ))
                { 
                    sock.Close();
                    
return   false ;
                }
                sendData(sock, message.Encode());
                sendData(sock, 
" . " );
                
if ( ! checkResponse(sock,  250 ))
                { 
                    sock.Close();
                    
return   false ;
                } 

                
//  QUIT
                sendData(sock,  " QUIT " );
                checkResponse(sock, 
221 );
                sock.Close(); 
                
return   true ;
            }
            
catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e.Message);
                
return   false ;
            }
        }

        
///   <summary>
        
///  发送数据到服务器。
        
///   </summary>
        
///   <param name="sock"></param>
        
///   <param name="msg"></param>
         private   void  sendData(Socket sock,  string  msg)
        { 
            
byte [] s  =  Encoding.ASCII.GetBytes(msg);
            sock.Send(s, 
0 , s.Length, SocketFlags.None);
        }

        
///   <summary>
        
///  检查服务器返回指令。
        
///   </summary>
        
///   <param name="sock"></param>
        
///   <param name="responseExpected"></param>
        
///   <returns></returns>
         private   bool  checkResponse(Socket sock,  int  responseExpected)
        {
            
string  sResponse;
            
int  response;
            
byte [] bytes  =   new   byte [ 1024 ];
            
while  (sock.Available  ==   0 )
            {
                System.Threading.Thread.Sleep(
100 );
            }

            sock.Receive(bytes, 
0 , sock.Available, SocketFlags.None);
            sResponse 
=  Encoding.ASCII.GetString(bytes);

            response 
=  Convert.ToInt32(sResponse.Substring( 0 3 ));
            
if (response  !=  responseExpected)  return   false ;

            
return   true ;
        }
    }
    
#endregion
}

/*  **********************************************
 * Rainsoft Development Library for Microsoft.NET
 * 
 * Copyright (c) 2004,2005 RainTrail Studio.China
 * All Rigths Reserved!
 * Author: Q.yuhen (qyuhen@hotmail.com)
 ********************************************** 
*/

namespace  Rainsoft.Network
{
    
#region  DnsMX
    
///   <summary>
    
///  DnsMX 结构
    
///   </summary>
     public   struct  MXRecord 
    {
        
///   <summary>
        
///  优先级
        
///   </summary>
         public   int  Preference;
    
        
///   <summary>
        
///  主机地址
        
///   </summary>
         public   string  Exchange;

        
///   <summary>
        
///  转换成字符串
        
///   </summary>
        
///   <returns></returns>
         public   override   string  ToString()
        {
            
return  Exchange  +   " : "   +  Preference.ToString();
        }
    }
    
#endregion

    
///   <summary>
    
///  通过 DNS 服务器查询邮件服务器 MX 记录
    
///   </summary>
    
///   <example>
    
///   <code>
    
///  DnsMX mx = new DnsMX();
    
///  mx.AddDnsServer("158.152.1.58");
    
///  MXRecord[] results = mx.GetMXRecords("263.net");
    
///  
    
///  foreach(MXRecord m in results) 
    
///  {
    
///     Console.WriteLine(m);
    
///  }
    
///   </code>
    
///   </example>
     public   sealed   class  DnsMX
    {
        
private   byte [] data;
        
private   int  position, id, length;
        
private   string  name;
        
private  ArrayList dnsServers;
        
private   static   int  DNS_PORT  =   53 ;
        
private  System.Text.Encoding ASCII  =  Encoding.ASCII;

        
///   <summary>
        
///  构造
        
///   </summary>
         public  DnsMX() 
        {
            id 
=  DateTime.Now.Millisecond  *   60 ;
            dnsServers 
=   new  ArrayList();
        }

        
///   <summary>
        
///  添加 DNS 服务器
        
///   </summary>
        
///   <param name="dnsServer"></param>
         public   void  AddDnsServer( string  dnsServer)
        {
            
this .dnsServers.Add(dnsServer);
        }

        
///   <summary>
        
///  添加 DNS 服务器
        
///   </summary>
        
///   <param name="dnsServers"></param>
         public   void  AddDnsServer(System.Collections.ICollection dnsServers)
        {
            
this .dnsServers.AddRange(dnsServers);
        }

        
///   <summary>
        
///  返回 MX 记录
        
///   </summary>
        
///   <param name="host"></param>
        
///   <returns></returns>
         public  MXRecord[] GetMXRecords( string  host) 
        {
            MXRecord[] result 
=   null ;
            
foreach ( object  o  in  dnsServers) 
            {
                
try  
                {
                    result 
=  getMXRecords(host, ( string )o);
                    
break ;
                }
                
catch (IOException) 
                {
                    
continue ;
                }
            }

            
return  result;
        }

        
///   <summary>
        
///  网络查询 
        
///   </summary>
        
///   <param name="host"></param>
        
///   <param name="serverAddress"></param>
        
///   <returns></returns>
         private  MXRecord[] getMXRecords( string  host,  string  serverAddress) 
        {
            UdpClient dnsClient 
=   new  UdpClient(serverAddress, DNS_PORT);
            makeQuery(
++ id, host);
            dnsClient.Send(data, data.Length);

            IPEndPoint endpoint 
=   null ;
            data 
=  dnsClient.Receive( ref  endpoint);
            length 
=  data.Length;

            
return  makeResponse();
        }

        
///   <summary>
        
///  构造查询包
        
///   </summary>
        
///   <param name="id"></param>
        
///   <param name="name"></param>
         private   void  makeQuery( int  id, String name) 
        {
            data 
=   new   byte [ 512 ];
            
for ( int  i  =   0 ; i  <   512 ++ i) data[i]  =   0 ;

            data[
0 ]    =  ( byte ) (id  >>   8 );
            data[
1 =  ( byte ) (id  &   0xFF  );
            data[
2 =  ( byte 1 ; data[ 3 =  ( byte 0 ;
            data[
4 =  ( byte 0 ; data[ 5 =  ( byte 1 ;
            data[
6 =  ( byte 0 ; data[ 7 =  ( byte 0 ;
            data[
8 =  ( byte 0 ; data[ 9 =  ( byte 0 ;
            data[
10 =  ( byte 0 ; data[ 11 =  ( byte 0 ;

            
string [] tokens  =  name.Split( new   char [] { ' . ' });
            
string  label;

            position 
=   12 ;

            
for ( int  j  =   0 ; j  <  tokens.Length; j ++
            {
                label 
=  tokens[j];
                data[position
++ =  ( byte ) (label.Length  &   0xFF );
                
byte [] b  =  ASCII.GetBytes(label);

                
for ( int  k = 0 ; k  <  b.Length; k ++
                {
                    data[position
++ =  b[k];
                }
            }

            data[position
++ =  ( byte 0  ; data[position ++ =  ( byte 0 ;
            data[position
++ =  ( byte 15 ; data[position ++ =  ( byte 0  ;
            data[position
++ =  ( byte 1  ;
        }

        
///   <summary>
        
///  分解反馈包
        
///   </summary>
        
///   <returns></returns>
         private  MXRecord[] makeResponse() 
        {
            ArrayList list 
=   new  ArrayList();
            MXRecord mx;

            
int  qCount  =  ((data[ 4 &   0xFF <<   8 |  (data[ 5 &   0xFF );
            
if  (qCount  <   0 throw   new  IOException( " invalid question count " );

            
int  aCount  =  ((data[ 6 &   0xFF <<   8 |  (data[ 7 &   0xFF );
            
if  (aCount  <   0 throw   new  IOException( " invalid answer count " );

            position
= 12 ;

            
for int  i  =   0 ; i  <  qCount;  ++ i) 
            {
                name 
=   "" ;
                position 
=  proc(position);
                position 
+=   4 ;
            }

            
for  ( int  i  =   0 ; i  <  aCount;  ++ i) 
            {
                name 
=   "" ;
                position 
=  proc(position);

                position
+= 10 ;

                
int  pref  =  (data[position ++ <<   8 |  (data[position ++ &   0xFF );

                name 
=   "" ;
                position 
=  proc(position);

                mx.Preference 
=  pref;
                mx.Exchange 
=  name;

                list.Add(mx);
            }

            
return  (MXRecord[])list.ToArray( typeof (MXRecord));
        }

        
private   int  proc( int  position) 
        {
            
int  len  =  (data[position ++ &   0xFF );
            
if (len  ==   0 return  position;
            
int  offset;

            
do  
            {
                
if  ((len  &   0xC0 ==   0xC0
                {
                    
if  (position  >=  length)  return   - 1 ;
                    offset 
=  ((len  &   0x3F <<   8 |  (data[position ++ &   0xFF );
                    proc(offset);
                    
return  position;
                } 
                
else  
                {
                    
if  ((position  +  len)  >  length)  return   - 1 ;
                    name 
+=  ASCII.GetString(data, position, len);
                    position 
+=  len;
                }

                
if  (position  >  length)  return   - 1 ;
                len 
=  data[position ++ &   0xFF ;
                
if  (len  !=   0 ) name  +=   " . " ;
            }
            
while  (len  !=   0 );

            
return  position;
        }
    }
}

/*  **********************************************
 * Rainsoft Development Library for Microsoft.NET
 * 
 * Copyright (c) 2004,2005 RainTrail Studio.China
 * All Rigths Reserved!
 * Author: Q.yuhen (qyuhen@hotmail.com)
 ********************************************** 
*/  

namespace  Rainsoft.Text
{
    
///   <summary>
    
///  BASE64 编码
    
///   </summary>
     public   sealed   class  Base64
    {
        
private  Base64(){}

        
///   <summary>
        
///  对字符串进行 base64 编码。
        
///   </summary>
        
///   <param name="str"> 待编码的字符串 </param>
        
///   <returns></returns>
         public   static   string  String( string  str)
        {
            
try
            {
                
byte [] by  =  System.Text.Encoding.Default.GetBytes(str);
                str 
=  Convert.ToBase64String(by);
            }
            
catch (Exception)
            {
            }
            
return  str;
        }

        
///   <summary>
        
///  对文件进行 base64 编码。
        
///   </summary>
        
///   <param name="file"> 对文件进行编码 </param>
        
///   <returns></returns>
         public   static   string  File( string  file)
        {
            
byte [] binaryData;
            StringBuilder result 
=   new  StringBuilder();

            FileInfo info 
=   new  FileInfo(file);
            FileStream fs 
=   new  FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            
try
            {
                binaryData 
=   new  Byte[fs.Length];
                
long  bytesRead  =  fs.Read(binaryData,  0 , ( int )fs.Length);
                
string  base64String  =  System.Convert.ToBase64String(binaryData,  0 , binaryData.Length);

                
for ( int  i  =   0 ; i  <  base64String.Length ; )
                {
                    
int  nextchunk  =   100 ;
                    
if  (base64String.Length  -  (i  +  nextchunk )  <   0 ) nextchunk  =  base64String.Length  -  i;
                    result.Append(base64String.Substring(i, nextchunk));
                    result.Append(
" " );
                    i 
+=  nextchunk; 
                }

                
return  result.ToString();
            }
            
finally
            {
                fs.Close();
            }
        }
    }  
}




  


   
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值