www.pudn.com > C++biyesheji.rar > SendMail.cs


using System;  
using System.Text;  
using System.IO;  
using System.Net;  
using System.Net.Sockets;  
using System.Collections;  
using System.Runtime .InteropServices ; 
using System.Windows.Forms ; 
//正则表达式需要用到的命名空间(本程序中主要用于切割字符串) 
using System.Text .RegularExpressions ; 
namespace MailSend 
{ 
	public class SmtpMail  
	{  
		public SmtpMail() 
		{ 
			// 
			// TODO: 在此处添加构造函数逻辑 
			// 
		} 
 
		//用来接收调用程序传来的附件路径 
		private string []FilePath; 
		 
//		[DllImport("User32.dll")]  
//		public static extern int MessageBox(int h, string m, string c, int type);   
// 
 
		///  
		/// 重载的构造函数,以便把相关的附件信息传入 
		///  
		///  
		public SmtpMail(ArrayList array)  
		{  
			//在重载构造函数的同时,将FiilePath初始化 
			FilePath=new string [array.Count ]; 
			Attachments = new System.Collections.ArrayList();  
			for(int i=0;i  
		/// 设定语言代码,默认设定为GB2312,如不需要可设置为""  
		///   
		private string _charset="GB2312";  
 
		///   
		/// 发件人地址  
		///   
		private string _from="";  
 
		///   
		/// 发件人姓名  
		///   
		private string _fromName="";  
 
		///   
		/// 回复邮件地址  
		///   
		///public string ReplyTo="";  
 
		///   
		/// 收件人列表  
		///   
		private string Recipient;  
 
		///   
		/// 邮件服务器域名  
		///   
		private string mailserver="";  
 
		///   
		/// 邮件服务器端口号  
		///   
		private int mailserverport=25;  
 
		///   
		/// SMTP认证时使用的用户名  
		///   
		private string username="";  
 
		///   
		/// SMTP认证时使用的密码  
		///   
		private string password="";  
 
		///   
		/// 是否需要SMTP验证  
		///   
		private bool ESmtp=false;  
 
		///   
		/// 是否Html邮件  
		///   
		private bool _html=false;  
 
 
		///   
		/// 邮件附件列表  
		///   
		private IList Attachments;  
 
		///   
		/// 邮件发送优先级,可设置为"High","Normal","Low"或"1","3","5"  
		///   
		private string priority="Normal";  
 
		///   
		/// 邮件主题  
		///   
		private string _subject;  
 
		///   
		/// 邮件正文  
		///   
		private string _body;  
	 
 
		///   
		/// 错误消息反馈  
		///   
		private string errmsg;  
 
		///   
		/// TcpClient对象,用于连接服务器  
		///   
		private TcpClient tc;  
 
		///   
		/// NetworkStream对象  
		///   
		private NetworkStream ns;  
 
		///   
		/// SMTP错误代码哈希表  
		///   
		private Hashtable ErrCodeHT = new Hashtable();  
 
		///   
		/// SMTP正确代码哈希表  
		///   
		private Hashtable RightCodeHT = new Hashtable();  
 
 
		///   
		/// 邮件主题  
		///   
		public string Subject  
		{  
			get  
			{  
				return this._subject;  
			}  
			set  
			{  
				this._subject = value;  
			}  
		}  
 
		///   
		/// 邮件正文  
		///   
		public string Body  
		{  
			get  
			{  
				return this._body;  
			}  
			set  
			{  
				this._body = value;  
			}  
		}  
 
 
		///   
		/// 发件人地址  
		///   
		public string From  
		{  
			get  
			{  
				return _from;  
			}  
			set  
			{  
				this._from = value;  
			}  
		}  
 
		///   
		/// 设定语言代码,默认设定为GB2312,如不需要可设置为""  
		///   
		public string Charset  
		{  
			get  
			{  
				return this._charset;  
			}  
			set  
			{  
				this._charset = value;  
			}  
		}  
 
		///   
		/// 发件人姓名  
		///   
		public string FromName  
		{  
			get  
			{  
				return this._fromName;  
			}  
			set  
			{  
				this._fromName = value;  
			}  
		}  
 
		///   
		/// 收件人姓名  
		///   
		public string RecipientName  
		{  
			get  
			{  
				return this.Recipient;  
			}  
			set  
			{  
				this.Recipient = value;  
			}  
		}  
 
		///   
		/// 邮件服务器域名和验证信息  
		/// 形如:"user:pass@www.server.com:25",也可省略次要信息。如"user:pass@www.server.com"或"www.server.com"  
		///   
		public string MailDomain  
		{  
			set  
			{  
				mailserver=value;  
 
			}  
 
				 
		}  
 
 
 
		///   
		/// 邮件服务器端口号  
		///   
		public int MailDomainPort  
		{  
			set  
			{  
				mailserverport=value;  
			}  
		}  
 
 
 
		///   
		/// SMTP认证时使用的用户名  
		///   
		public string MailServerUserName  
		{  
			set  
			{  
				if(value.Trim()!="")  
				{  
					username=value.Trim();  
					ESmtp=true;  
				}  
				else  
				{  
					username="";  
					ESmtp=false;  
				}  
			}  
		}  
 
		///   
		/// SMTP认证时使用的密码  
		///   
		public string MailServerPassWord  
		{  
			set  
			{  
				password=value;  
			}  
		}  
 
		///   
		/// 邮件发送优先级,可设置为"High","Normal","Low"或"1","3","5"  
		///   
		public string Priority  
		{  
			set  
			{  
				switch(value.ToLower())  
				{  
					case "high":  
						priority="High";  
						break;  
 
					case "1":  
						priority="High";  
						break;  
 
					case "normal":  
						priority="Normal";  
						break;  
 
					case "3":  
						priority="Normal";  
						break;  
 
					case "low":  
						priority="Low";  
						break;  
 
					case "5":  
						priority="Low";  
						break;  
 
					default:  
						priority="Normal";  
						break;  
				}  
			}  
		}  
 
		///   
		/// 是否Html邮件  
		///   
		public bool Html  
		{  
			get  
			{  
				return this._html;  
			}  
			set  
			{  
				this._html = value;  
			}  
		}  
 
 
		///   
		/// 错误消息反馈  
		///   
		public string ErrorMessage  
		{  
			get  
			{  
				return errmsg;  
			}  
		}  
	 
 
		public bool eSmtp 
		{ 
			get 
			{ 
				return this.ESmtp; 
			} 
			set 
			{ 
				this.ESmtp =value; 
			} 
		} 
			 
 
 
		///   
		/// 添加邮件附件  
		///   
		/// 附件绝对路径  
		public void AddAttachment(params string[] FilePath)  
		{  
			try 
			{ 
				if(FilePath==null)  
				{  
					throw(new ArgumentNullException("FilePath"));  
				}  
				for(int i=0;i  
		/// 得到上传附件的文件流  
		///   
		/// 附件的绝对路径  
		private string GetStream(string FilePath)  
		{  
			try 
			{ 
				//建立文件流对象  
				System.IO.FileStream FileStr=new System.IO.FileStream(FilePath,System.IO.FileMode.Open);  
				byte[] by=new byte[System.Convert.ToInt32(FileStr.Length)];  
				FileStr.Read(by,0,by.Length);  
				FileStr.Close();  
				return(System.Convert.ToBase64String(by));  
			} 
			catch 
			{ 
				MessageBox.Show ("可能你要打开的文件的属性是只读的!","请检查权限"); 
				return null; 
			} 
		}  
 
 
		///   
		/// 发送邮件方法,所有参数均通过属性设置。  
		///   
		public bool Send()  
		{  
			if(mailserver.Trim()=="")  
			{  
				MessageBox.Show ("必须指定SMTP服务器");  
				return false; 
			}  
 
			return SendEmail();  
 
		}  
 
 
		///   
		/// 发送邮件方法  
		///   
		/// smtp服务器信息,如"username:password@www.smtpserver.com:25",也可去掉部分次要信  
 
			 
		public bool Send(string smtpserver)  
		{  
			MailDomain=smtpserver;  
			return Send();  
		}  
 
 
		///   
		/// 发送邮件方法  
		///   
		/// smtp服务器信息,如"username:password@www.smtpserver.com:25",也可去掉部分次要信  
 
			 
		/// 发件人mail地址  
		/// 发件人姓名  
		/// 收件人地址  
		/// 收件人姓名  
		/// 是否HTML邮件  
		/// 邮件主题  
		/// 邮件正文  
		public bool Send(string smtpserver,string from,string fromname,string to,bool html,string  
 
			subject,string body)  
		{  
			MailDomain=smtpserver;  
			From=from;  
			FromName=fromname;  
			Recipient=to;  
			Html=html;  
			Subject=subject;  
			Body=body;  
			return Send();  
		}  
 
 
		void Dispose()  
		{  
			if(ns!=null)ns.Close();  
			if(tc!=null)tc.Close();  
		}  
 
		///   
		/// SMTP回应代码哈希表  
		///   
		private void SMTPCodeAdd()  
		{  
			ErrCodeHT.Add("500","邮箱地址错误");  
			ErrCodeHT.Add("501","参数格式错误");  
			ErrCodeHT.Add("502","命令不可实现");  
			ErrCodeHT.Add("503","服务器需要SMTP验证");  
			ErrCodeHT.Add("504","命令参数不可实现");  
			ErrCodeHT.Add("421","服务未就绪,关闭传输信道");  
			ErrCodeHT.Add("450","要求的邮件操作未完成,邮箱不可用(例如,邮箱忙)");  
			ErrCodeHT.Add("550","要求的邮件操作未完成,邮箱不可用(例如,邮箱未找到,或不可访问)");  
			ErrCodeHT.Add("451","放弃要求的操作;处理过程中出错");  
			ErrCodeHT.Add("551","用户非本地,请尝试");  
			ErrCodeHT.Add("452","系统存储不足,要求的操作未执行");  
			ErrCodeHT.Add("552","过量的存储分配,要求的操作未执行");  
			ErrCodeHT.Add("553","邮箱名不可用,要求的操作未执行(例如邮箱格式错误)");  
			ErrCodeHT.Add("432","需要一个密码转换");  
			ErrCodeHT.Add("534","认证机制过于简单");  
			ErrCodeHT.Add("538","当前请求的认证机制需要加密");  
			ErrCodeHT.Add("454","临时认证失败");  
			ErrCodeHT.Add("530","需要认证");  
 
			RightCodeHT.Add("220","服务就绪");  
			RightCodeHT.Add("250","要求的邮件操作完成");  
			RightCodeHT.Add("251","用户非本地,将转发向");  
			RightCodeHT.Add("354","开始邮件输入,以.结束");  
			RightCodeHT.Add("221","服务关闭传输信道");  
			RightCodeHT.Add("334","服务器响应验证Base64字符串");  
			RightCodeHT.Add("235","验证成功");  
		}  
 
 
		///   
		/// 将字符串编码为Base64字符串  
		///   
		/// 要编码的字符串  
		private string Base64Encode(string str)  
		{  
			byte[] barray;  
			barray=Encoding.Default.GetBytes(str);  
			return Convert.ToBase64String(barray);  
		}  
 
 
		///   
		/// 将Base64字符串解码为普通字符串  
		///   
		/// 要解码的字符串  
		private string Base64Decode(string str)  
		{  
			byte[] barray;  
			barray=Convert.FromBase64String(str);  
			return Encoding.Default.GetString(barray);  
		}  
 
 
			 
		///   
		/// 发送SMTP命令  
		///   
		private bool SendCommand(string str)  
		{  
			byte[] WriteBuffer;  
			if(str==null||str.Trim()==String.Empty)  
			{  
				return true;  
			}  
 
			WriteBuffer = Encoding.Default.GetBytes(str);  
			try  
			{  
				ns.Write(WriteBuffer,0,WriteBuffer.Length);  
			}  
			catch  
			{  
				errmsg="网络连接错误";  
				return false;  
			}  
			return true;  
		}  
 
		///   
		/// 接收SMTP服务器回应  
		///   
		private string RecvResponse()  
		{  
			int StreamSize;  
			string ReturnValue = String.Empty;  
			byte[] ReadBuffer = new byte[1024] ;  
			try  
			{  
				StreamSize=ns.Read(ReadBuffer,0,ReadBuffer.Length);  
			}  
			catch(Exception ex) 
			{  
				MessageBox.Show (ex.ToString ()); 
				return "false";  
			}  
 
			if (StreamSize==0)  
			{  
				return ReturnValue ;  
			}  
			else  
			{  
				ReturnValue = Encoding.Default.GetString(ReadBuffer).Substring(0,StreamSize);  
				return ReturnValue;  
			}  
		}  
 
		///   
		/// 与服务器交互,发送一条命令并接收回应。  
		///   
		/// 一个要发送的命令  
		/// 如果错误,要反馈的信息  
		private bool Dialog(string str,string errstr)  
		{  
				 
			if(str==null||str.Trim()=="")  
			{  
				return true;  
			}  
			if(SendCommand(str))  
			{  
				string RR=RecvResponse();  
				if(RR=="false")  
				{  
					return false;  
				}  
				try 
				{ 
					string RRCode=RR.Substring(0,3);  
					if(RightCodeHT[RRCode]!=null)  
					{  
						return true;  
					}  
					else  
					{  
						if(ErrCodeHT[RRCode]!=null)  
						{  
							errmsg+=(RRCode+ErrCodeHT[RRCode].ToString());  
							errmsg+=enter;  
						}  
						else  
						{  
							errmsg+=RR;  
						}  
						errmsg+=errstr;  
						return false;  
					}  
				} 
				catch 
				{ 
					MessageBox.Show ("发送的附件超过本服务器对个人软件的支持!","请检查附件的大小"); 
					return false; 
				} 
			}  
			else  
			{  
				return false;  
			}  
		} 
				 
		///   
		/// 与服务器交互,发送一组命令并接收回应。  
		///   
 
		private bool Dialog(string[] str,string errstr)  
		{  
			for(int i=0;i  
		/// SendEmail  
		///   
		///   
		private bool SendEmail()  
		{  
			try  
			{  
				tc=new TcpClient(mailserver,mailserverport);  
			}  
			catch 
			{  
				MessageBox.Show ("连接失败","请确认"); 
				return false;  
			}  
 
			ns = tc.GetStream();  
			SMTPCodeAdd();  
 
			//验证网络连接是否正确  
			if(RightCodeHT[RecvResponse().Substring(0,3)]==null)  
			{  
				errmsg="网络连接失败";  
				return false;  
			}  
 
 
			string[] SendBuffer;  
			string SendBufferstr;  
 
			//进行SMTP验证  
			if(ESmtp)  
			{  
				SendBuffer=new String[4];  
				SendBuffer[0]="EHLO " + mailserver + enter;  
				SendBuffer[1]="AUTH LOGIN" + enter;  
				SendBuffer[2]=Base64Encode(username) + enter;  
				SendBuffer[3]=Base64Encode(password) + enter;  
				if(!Dialog(SendBuffer,"SMTP服务器验证失败,请核对用户名和密码。")) 
				{ 
					MessageBox.Show ("SMTP服务器验证失败,请核对用户名和密码。"); 
					return false; 
				} 
			}  
			else  
			{  
				SendBufferstr="HELO " + mailserver + enter;  
				if(!Dialog(SendBufferstr,""))  
					return false;  
			}  
 
			//  
			SendBufferstr="MAIL FROM:<" + From + ">" + enter;  
			if(!Dialog(SendBufferstr,"发件人地址错误,或不能为空")) 
			{ 
				MessageBox.Show("发件人地址错误,或不能为空"); 
				return false;  
			} 
 
			  
			//把传过来的收件人的地址分割然后提交给服务器 
			string split=","; 
			string []address=Regex.Split (RecipientName,split); 
			SendBuffer=new string [address.Length]; 
			for(int i=0;i" + enter; 
			} 
			if(!Dialog(SendBuffer,"收件人地址有误"))  
			{ 
				MessageBox.Show("收件人地址有误"); 
				return false;  
			} 
 
				 
			SendBufferstr="DATA" + enter;  
			if(!Dialog(SendBufferstr,""))  
				return false;  
 
			SendBufferstr="From:" + FromName + "<" + From +">" +enter;  
			SendBufferstr += "To:<"+RecipientName+">"+enter; 
			 
			 
 
			SendBufferstr+=((Subject==String.Empty || Subject==null)?"Subject:":((Charset=="")?("Subject:" +  
 
				Subject):("Subject:" + "=?" + Charset.ToUpper() + "?B?" + Base64Encode(Subject) +"?="))) + enter;  
			SendBufferstr+="X-Priority:" + priority + enter;  
			SendBufferstr+="X-Mailer: ArgentSwan Mail Sender" + enter;  
			SendBufferstr+="MIME-Version: 1.0" + enter;  
 
			//MIME定义了5个新的信头字段,可以与原有信头字段一样,用在RF822邮件的首部中。 
			//1.MIME版本信头字段				格式:MIME-Version:1.0  
			//2.邮件唯一标识信头字段			格式:Content-ID:唯一标识信件的字符串   
			//3.邮件内容描述信头字段			格式:Content-Description:描述文本  
			//4.MIME邮件的内容类型信头字段		格式:Content-Type:主类别标识符/子类别标识符 [;参数列表]   
			//5.内容传送编码方式信头字段		格式:Content-Transfer-Encoding:编码方式标识符  
 
			if(Attachments.Count!=0)  
			{  
				//mixed	 按照特定顺序的几个独立部分 
				SendBufferstr+="Content-Type: multipart/mixed;" + enter;  
				SendBufferstr += " boundary=\"***"+  
 
					(Html?"001_yinhu19821115":"001_yinhu19831115")+"***\""+enter+enter;  
			}  
 
			if(Html)  
			{  
				if(Attachments.Count==0)  
				{  
					//multipart多部分  alternative 不同格式的同一邮件 
					SendBufferstr += "Content-Type: multipart/alternative;"+enter;//内容格式和分隔符  
					SendBufferstr += " boundary=\"***003_yinhu19821115***\""+enter+enter;  
 
					SendBufferstr += "This is a multi-part message in MIME format."+enter+enter;  
				}  
				else  
				{  
					SendBufferstr +="This is a multi-part message in MIME format."+enter+enter;  
					SendBufferstr += "--***001_yinhu19821115***"+enter;  
					SendBufferstr += "Content-Type: multipart/alternative;"+enter;//内容格式和分隔符  
					SendBufferstr += " boundary=\"***003_yinhu19821115***\""+enter+enter;  
 
 
				} 
				SendBufferstr += "--***003_yinhu19821115***"+enter;  
				SendBufferstr += "Content-Type: text/plain;"+ enter;  
				SendBufferstr += ((Charset=="")?(" charset=\"iso-8859-1\""):(" charset=\"" +  
 
					Charset.ToLower() + "\"")) + enter;  
				SendBufferstr+="Content-Transfer-Encoding: base64" + enter + enter;  
				SendBufferstr+= Base64Encode("邮件内容为HTML格式,请选择HTML方式查看") + enter + enter;  
 
				SendBufferstr += "--***003_yinhu19821115***"+enter;  
 
 
 
				SendBufferstr+="Content-Type: text/html;" + enter;  
				SendBufferstr+=((Charset=="")?(" charset=\"iso-8859-1\""):(" charset=\"" +  
 
					Charset.ToLower() + "\"")) + enter;  
				SendBufferstr+="Content-Transfer-Encoding: base64" + enter + enter;  
				SendBufferstr+=Base64Encode(Body)+ enter + enter;  
				SendBufferstr += "--***003_yinhu19821115***--"+enter;  
			}  
			else  
			{  
				if(Attachments.Count!=0)  
				{  
					SendBufferstr += "--***001_yinhu19831115***"+enter;  
				}  
				SendBufferstr+="Content-Type: text/plain;" + enter;  
				SendBufferstr+=((Charset=="")?(" charset=\"iso-8859-1\""):(" charset=\"" +  
 
					Charset.ToLower() + "\"")) + enter;  
				SendBufferstr+="Content-Transfer-Encoding: base64" + enter + enter;  
				SendBufferstr+= Base64Encode(Body) + enter;  
			}  
 
 
			if(Attachments.Count!=0)  
			{  
				for(int i=0;i