using System; using System.Net.Sockets;//用于处理网络连接 using System.IO; //用于处理附件的包 using System.Text;//用于处理文本编码 using System.Data; using System.Net;
namespace PublicClass { /// <summary> /// CEMailCtr SMTP类,支持ESMTP。 /// </summary> public class CEMailCtr:TcpClient { private String server;//SMTP服务器域名 private int port;//端口 private String username="";//用户名 private String password="";//密码 private String subject="";//主题 private String body="";//文本内容 private String htmlbody="";//超文本内容 private String from="";//发件人地址 private String to="";//收件人地址 private String cc=""; private String bcc=""; private String fromname="";//发件人姓名 private String toname="";//收件人姓名 private String content_type;//邮件类型 private String encode;//邮件编码 private String charset;//语言编码 private DataTable filelist;//附件列表 private int priority;//邮件优先级 // private bool bIsExtend = false; private string strErrMsg="";
public CEMailCtr() { // TOD 在此处添加构造函数逻辑 filelist=new DataTable();//已定义变量,初始化操作 filelist.Columns.Add(new DataColumn("filename",typeof(String)));//文件名 filelist.Columns.Add(new DataColumn("filecontent",typeof(String)));//文件内容 this.charset ="GB2312" ; this.encode ="base64"; this.port =25; } /// <summary> /// 服务器 /// </summary> public String Server { set{server = value; } get{return server; } }
/// <summary> /// 发件人地址 /// </summary> public String From { set{from = value;} get{return from;} }
/// <summary> /// 发件人姓名 /// </summary> public String FromName { set{fromname = value;} get{return fromname;} }
/// <summary> /// 邮箱密码 /// </summary> public String Password { set{password = value;} get{return password;} }
/// <summary> /// 服务器端口 /// </summary> public int Port { set{port =value;} get{return port;} }
/// <summary> /// 邮件优先级 /// </summary> public int Priority { set{priority = value;} get{return priority;} }
/// <summary> /// 主题 /// </summary> public String Subject { set{subject = value;} get{return subject;} }
/// <summary> /// 收件人地址 /// </summary> public String To { set{to = value;} get{return to;} }
public String Cc { set{cc =value;} get{return cc;} }
public String Bcc { set{bcc = value;} get{return bcc;} }
/// <summary> /// 收件人姓名 /// </summary> public String ToName { set{toname=value;} get{return toname;} }
/// <summary> /// 用户名 /// </summary> public String UserName { set{username = value;} get{return username;} }
/// <summary> /// 邮件内容 /// </summary> public String Body { set { body = value; if((htmlbody ==null) || (htmlbody =="")) HtmlBody = body; } }
/// <summary> /// 邮件内容(html) /// </summary> public String HtmlBody { set{htmlbody = value;} }
/// <summary> /// 语言编码 /// </summary> public string Charset { get{return this.charset ;} set{charset = value;} }
/// <summary> /// 邮件编码 /// </summary> public string Encode { get{return this.encode ;} set{this.encode = value;} }
/// <summary> /// 扩展SMTP标志 /// </summary> public bool isExtend { get{return bIsExtend;} set{bIsExtend = value;} }
/// <summary> /// 发送数据 /// </summary> /// <param name="strCmd"></param> private void writeStream(String strCmd) { writeStream(strCmd,this.charset ); }
/// <summary> /// 发送数据 /// </summary> /// <param name="strCmd"></param> /// <param name="charset"></param> private void writeStream(String strCmd,String charset) { Stream TcpStream;//定义操作对象 strCmd = strCmd + "\r\n"; //加入换行符 TcpStream =this.GetStream();//获取数据流 //将命令行转化为byte[] byte[] bWrite = Encoding.GetEncoding(charset).GetBytes(strCmd.ToCharArray()); //由于每次写入的数据大小是有限制的,那么我们将每次写入的数据长度定在75个字节,一旦命令长度超过了75,就分步写入。 int start=0; int length=bWrite.Length; int page=0; int size=75; int count=size; try { if ( length > 75 ) { //数据分页 if ( (length % size) >0 ) page = length/size + 1; else page=length/size; for (int i=0;i < page ; i++ ) { start=i*size; if (i== page - 1 ) count=length-(i*size); TcpStream.Write(bWrite,start,count);//将数据写入到服务器上 } } else TcpStream.Write(bWrite,0,bWrite.Length); } catch(Exception e) { throw new Exception(e.Message); } }
/// <summary> /// 接收数据 /// </summary> /// <returns></returns> private String receiveStream() { String sp=null; byte[] by=new byte[1024]; NetworkStream ns = this.GetStream();//此处即可获取服务器的返回数据流 int size=ns.Read(by,0,by.Length);//读取数据流 if (size>0) { sp=Encoding.Default.GetString(by);//转化为String } return sp; }
/// <summary> /// 写入命令并对状态作判断 /// </summary> /// <param name="strCmd">命令行</param> /// <param name="state">状态码</param> /// <returns></returns> private bool operaStream(String strCmd,String state) { String sp=null; bool success=false; try { writeStream(strCmd);//写入命令 sp = receiveStream();//接受返回信息 if (sp.IndexOf(state)!=-1)//判断状态码是否正确 success=true; } catch(Exception ex) { throw new Exception (ex.Message); } return success; }
/// <summary> /// 连接到服务器 /// </summary> /// <returns></returns> private bool GetMailServer() { try { //域名解析 System.Net.IPAddress ipaddress=(IPAddress)System.Net.Dns.Resolve(this.server).AddressList.GetValue(0); System.Net.IPEndPoint endpoint=new IPEndPoint(ipaddress,port); Connect(endpoint);//连接Smtp服务器 receiveStream();//获取连接信息 if (bIsExtend) { //开始进行服务器认证 //如果状态码是250则表示操作成功 if (!operaStream("EHLO Localhost","250")) { this.Close(); return false; } if (!operaStream("AUTH LOGIN","334")) { this.Close(); return false; } username=authStream(username);//此处将username转换为Base64码 if (!operaStream(this.username,"334")) { this.Close(); return false; } password=authStream(password);//此处将password转换为Base64码 if (!operaStream(this.password,"235")) { this.Close(); return false; } } else { //如果服务器不需要认证 if (operaStream("HELO Localhost","250")) { return true; } else { return false; } } } catch(Exception e) { strErrMsg = e.Message; return false; } return true; } /// <summary> /// 编码转化成base64 /// </summary> /// <param name="strCmd"></param> /// <returns></returns> private String authStream(String strCmd) { try { byte[] by=Encoding.Default.GetBytes(strCmd.ToCharArray()); strCmd=Convert.ToBase64String(by); } catch(Exception ex) { strErrMsg = ex.Message; return ""; } return strCmd; }
/// <summary> /// 加载附件 /// </summary> /// <param name="path">文件路径</param> public void LoadAttFile(String path) { //根据路径读出文件流 FileStream fstr=new FileStream(path,FileMode.Open);//建立文件流对象 byte[] by=new byte[Convert.ToInt32(fstr.Length)]; fstr.Read(by,0,by.Length);//读取文件内容 fstr.Close();//关闭 //格式转换 String fileinfo=Convert.ToBase64String(by);//转化为base64编码 //增加到文件表中 //StreamReader sr = new StreamReader(fstr,System.Text.Encoding .Default ); //string fileinfo = sr.ReadToEnd (); DataRow dr=filelist.NewRow(); dr[0]=Path.GetFileName(path);//获取文件名 dr[1]=fileinfo;//文件内容 filelist.Rows.Add(dr);//增加 } /// <summary> /// 附件发送 /// </summary> private void attachment() { //对文件列表做循环 foreach (DataRow dr in filelist.Rows) { writeStream("--unique-boundary-1");//邮件内容分隔符 writeStream("Content-Type: application/octet-stream;name=\""+dr[0].ToString()+"\"");//文件格式 writeStream("Content-Transfer-Encoding:base64");//内容的编码 writeStream("Content-Disposition:attachment;filename=\""+dr[0].ToString()+"\"");//文件名 writeStream(""); String fileinfo=dr[1].ToString(); writeStream(fileinfo);//写入文件的内容 writeStream(""); } }
/// <summary> /// 发送 /// </summary> public bool send() { if( !GetMailServer() ) { strErrMsg = "无法连接服务器"; return false; } try { // operaStream("MAIL FROM:" + this.from,"250" ); if(to ==null) { strErrMsg ="收件人为空"; return false; } string[] strTo = this.to.Split (';'); for(int i=0; i<strTo.Length ; i++) { strTo[i] = strTo[i].Trim (); if (strTo[i] !="") operaStream("RCPT T" + strTo[i] ,"250"); } if( cc ==null) cc =""; string[] strCc = this.cc.Split(';'); for(int j=0; j<strCc.Length ; j++) { strCc[j] = strCc[j].Trim (); if(strCc[j] !="") operaStream("RCPT T" + strCc[j] ,"250"); } if(bcc ==null) bcc =""; string[] strBcc = this.bcc.Split (';'); for(int k=0; k<strBcc.Length ; k++) { strBcc[k] = strBcc[k].Trim (); if(strBcc[k] !="") operaStream("RCPT T" + strBcc[k] ,"250"); }
operaStream("DATA","250"); // writeStream("Date: "+DateTime.Now);//时间 writeStream("From: "+this.fromname+"<"+this.from+">");//发件人 writeStream("Subject: "+this.subject);//主题 //writeStream("T"+this.to);//收件人 string sTmp="T"; for(int i=0; i<strTo.Length ; i++) { sTmp += i>0?",":""; sTmp += strTo[i]; } writeStream(sTmp); sTmp="Cc:"; for(int j=0; j<strCc.Length; j++) { sTmp += j>0?",":""; sTmp += strCc[j]; } writeStream(sTmp); sTmp ="Bcc:"; for(int k=0; k<strBcc.Length ; k++) { sTmp += k>0?",":""; sTmp += strBcc[k]; } writeStream(sTmp); //邮件格式 writeStream("Content-Type: multipart/mixed; boundary=\"unique-boundary-1\""); writeStream("Reply-T"+this.from);//回复地址 //writeStream("X-Priority:"+this.priority );//优先级 writeStream("MIME-Version:1.0");//MIME版本 //数据ID,随意 writeStream("Message-Id: "+DateTime.Now.ToFileTime()+"@homeway.com.cn"); //writeStream("Content-Transfer-Encoding: "+this.encode);//内容编码 Content-Transfer-Encoding: base64 writeStream("X-Mailer:DS Mail Sender V1.0");//邮件发送者 writeStream(""); writeStream(authStream("This is a multi-part message in MIME format.")); writeStream(""); //从此处开始进行分隔输入 writeStream("--unique-boundary-1"); //在此处定义第二个分隔符 writeStream("Content-Type: multipart/alternative;Boundary=\"unique-boundary-2\""); writeStream(""); //文本信息 writeStream("--unique-boundary-2"); writeStream("Content-Type: text/plain;charset="+this.charset); //writeStream("Content-Transfer-Encoding:"+this.encode); writeStream(""); writeStream(body); writeStream("");//一个部分写完之后就写如空信息,分段 //html信息 writeStream("--unique-boundary-2"); writeStream("Content-Type: text/html;charset="+this.charset); //writeStream("Content-Transfer-Encoding: "+this.encode); writeStream(""); writeStream(htmlbody); writeStream(""); writeStream("--unique-boundary-2--");//分隔符的结束符号,尾巴后面多了-- writeStream(""); //增加附件 attachment(); writeStream(""); writeStream("--unique-boundary-1--"); operaStream(".","250"); } catch(Exception e) { strErrMsg = e.Message; return false; } finally { this.Close (); } return true; }
/// <summary> /// 取得错误信息 /// </summary> /// <returns></returns> public string GetErrMsg() { return strErrMsg; } } } /* 发送例子 public void sendemail(int sendflag) { //发送邮件 CEMailCtr mail = new CEMailCtr();
mail.isExtend = true; mail.Server = "192.168.0.1"; mail.Port = 25; mail.From = "da@xx.com"; mail.FromName = "da@xx.com";
mail.To = ToEmail; mail.ToName = ToUsername;
mail.UserName = "xx"; mail.Password = "xx"; string mybody = ""; if (sendflag==0) { mail.Subject = "关于执行任务通知"; mybody = " <font size=\"2\"> "+ " <b>"+ToUsername+"您好:</b></span><br> "+ " </font> "; } else { mail.Subject = "关于项目受理通知"; mybody = " <font size=\"2\"> "+ " <b>"+ToUsername+"您好:</b></span><br> "+ " </font> "; } mail.HtmlBody = mybody; mail.send(); } */