首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 认证考试-> Cisco认证
用c#写的smtp邮件发送类-.NET教程,C#语言
作者:网友供稿 点击:109
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
//**********************created by chen**************************
using system;
using system.io;
using system.text;
using system.net;
using system.net.sockets;
using system.collections;
using system.collections.specialized;
using ksn.exceptions;
using ksn.validate;
namespace ksn.web.mail
{
/// <summary>
/// 邮件内容
/// </summary>
public class mailmessage
{
private string sender=null;
private stringcollection receivers=new stringcollection();
private string subject="";
private string xmailer="";
private stringcollection attachments=new stringcollection();
private mailencodings mailencoding=mailencodings.gb2312;
private mailtypes mailtype=mailtypes.html;
private byte[] mailbody=null;
/// <summary>
/// 获取或设置发件人
/// </summary>
public string sender
{
get{return this.sender;}
set{this.sender=value;}
}
/// <summary>
/// 获取收件人地址集合
/// </summary>
public stringcollection receivers
{
get{return this.receivers;}
}
/// <summary>
/// 获取或设置邮件主题
/// </summary>
public string subject
{
get{return this.subject;}
set{this.subject=value;}
}
/// <summary>
/// 获取或设置邮件传送者
/// </summary>
public string xmailer
{
get{return this.xmailer;}
set{this.xmailer=value;}
}
/// <summary>
/// 获取附件列表
/// </summary>
public stringcollection attachments
{
get{return this.attachments;}
}
/// <summary>
/// 获取或设置邮件的编码方式
/// </summary>
public mailencodings mailencoding
{
get{return this.mailencoding;}
set{this.mailencoding=value;}
}
/// <summary>
/// 获取或设置邮件格式
/// </summary>
public mailtypes mailtype
{
get{return this.mailtype;}
set{this.mailtype=value;}
}
/// <summary>
/// 获取或设置邮件正文
/// </summary>
public byte[] mailbody
{
get{return this.mailbody;}
set{this.mailbody=value;}
}
}
/// <summary>
/// 邮件编码
/// </summary>
public enum mailencodings
{
gb2312,
ascii,
unicode,
utf8
}
/// <summary>
/// 邮件格式
/// </summary>
public enum mailtypes
{
html,
text
}
/// <summary>
/// smtp服务器的验证方式
/// </summary>
public enum smtpvalidatetypes
{
/// <summary>
/// 不需要验证
/// </summary>
none,
/// <summary>
/// 通用的auth login验证
/// </summary>
login,
/// <summary>
/// 通用的auth plain验证
/// </summary>
plain,
/// <summary>
/// cram-md5验证
/// </summary>
crammd5
}
/// <summary>
/// 邮件发送类
/// </summary>
public class ksn_smtp
{
#region "member fields"
/// <summary>
/// 连接对象
/// </summary>
private tcpclient tc;
/// <summary>
/// 网络流
/// </summary>
private networkstream ns;
/// <summary>
/// 错误的代码字典
/// </summary>
private stringdictionary errorcodes=new stringdictionary();
/// <summary>
/// 操作执行成功后的响应代码字典
/// </summary>
private stringdictionary rightcodes=new stringdictionary();
/// <summary>
/// 执行过程中错误的消息
/// </summary>
private string errormessage="";
/// <summary>
/// 记录操作日志
/// </summary>
private string logs="";
/// <summary>
/// 主机登陆的验证方式
/// </summary>
private stringcollection validatetypes=new stringcollection();
/// <summary>
/// 换行常数
/// </summary>
private const string crlf="\r\n";
private string servername="smtp";
private string logpath=null;
private string userid=null;
private string password=null;
private string mailencodingname="gb2312";
private bool sendiscomplete=false;
private smtpvalidatetypes smtpvalidatetype=smtpvalidatetypes.login;
#endregion
#region "propertys"
/// <summary>
/// 获取最后一此程序执行中的错误消息
/// </summary>
public string errormessage
{
get{return this.errormessage;}
}
/// <summary>
/// 获取或设置日志输出路径
/// </summary>
public string logpath
{
get
{
return this.logpath;
}
set{this.logpath=value;}
}
/// <summary>
/// 获取或设置登陆smtp服务器的帐号
/// </summary>
public string userid
{
get{return this.userid;}
set{this.userid=value;}
}
/// <summary>
/// 获取或设置登陆smtp服务器的密码
/// </summary>
public string password
{
get{return this.password;}
set{this.password=value;}
}
/// <summary>
/// 获取或设置要使用登陆smtp服务器的验证方式
/// </summary>
public smtpvalidatetypes smtpvalidatetype
{
get{return this.smtpvalidatetype;}
set{this.smtpvalidatetype=value;}
}
#endregion
#region "construct functions"
/// <summary>
/// 构造函数
/// </summary>
/// <param name="server">主机名</param>
/// <param name="port">端口</param>
public ksn_smtp(string server,int port)
{
tc=new tcpclient(server,port);
ns=tc.getstream();
this.servername=server;
this.initialfields();
}
/// <summary>
/// 构造函数
/// </summary>
/// <param name="ip">主机ip</param>
/// <param name="port">端口</param>
public ksn_smtp(ipaddress ip,int port)
{
ipendpoint endpoint=new ipendpoint(ip,port);
tc=new tcpclient(endpoint);
ns=tc.getstream();
this.servername=ip.tostring();
this.initialfields();
}
#endregion
#region "methods"
private void initialfields() //初始化连接
{
logs="================"+datetime.now.tolongdatestring()+" "+datetime.now.tolongtimestring()+"==============="+crlf;
//*****************************************************************
//错误的状态码
//*****************************************************************
errorcodes.add("421","服务未就绪,关闭传输通道");
errorcodes.add("432","需要一个密码转换");
errorcodes.add("450","要求的邮件操作未完成,邮箱不可用(如:邮箱忙)");
errorcodes.add("451","放弃要求的操作,要求的操作未执行");
errorcodes.add("452","系统存储不足,要求的操作未完成");
errorcodes.add("454","临时的认证失败");
errorcodes.add("500","邮箱地址错误");
errorcodes.add("501","参数格式错误");
errorcodes.add("502","命令不可实现");
errorcodes.add("503","命令的次序不正确");
errorcodes.add("504","命令参数不可实现");
errorcodes.add("530","需要认证");
errorcodes.add("534","认证机制过于简单");
errorcodes.add("538","当前请求的认证机制需要加密");
errorcodes.add("550","当前的邮件操作未完成,邮箱不可用(如:邮箱未找到或邮箱不能用)");
errorcodes.add("551","用户非本地,请尝试<forward-path>");
errorcodes.add("552","过量的存储分配,制定的操作未完成");
errorcodes.add("553","邮箱名不可用,如:邮箱地址的格式错误");
errorcodes.add("554","传送失败");
errorcodes.add("535","用户身份验证失败");
//****************************************************************
//操作执行成功后的状态码
//****************************************************************
rightcodes.add("220","服务就绪");
rightcodes.add("221","服务关闭传输通道");
rightcodes.add("235","验证成功");
rightcodes.add("250","要求的邮件操作完成");
rightcodes.add("251","非本地用户,将转发向<forward-path>");
rightcodes.add("334","服务器响应验证base64字符串");
rightcodes.add("354","开始邮件输入,以<crlf>.<crlf>结束");
//读取系统回应
streamreader reader=new streamreader(ns);
logs+=reader.readline()+crlf;
}
/// <summary>
/// 向smtp发送命令
/// </summary>
/// <param name="cmd"></param>
private string sendcommand(string cmd,bool ismaildata)
{
if(cmd!=null && cmd.trim()!=string.empty)
{
byte[] cmd_b=null;
if(!ismaildata)//不是邮件数据
cmd+=crlf;

logs+=cmd;
//开始写入邮件数据
if(!ismaildata)
{
cmd_b=encoding.ascii.getbytes(cmd);
ns.write(cmd_b,0,cmd_b.length);
}
else
{
cmd_b=encoding.getencoding(this.mailencodingname).getbytes(cmd);
ns.beginwrite(cmd_b,0,cmd_b.length,new asynccallback(this.asynccallback),null);
}
//读取服务器响应
streamreader reader=new streamreader(ns);
string response=reader.readline();
logs+=response+crlf;
//检查状态码
string statuscode=response.substring(0,3);
bool isexist=false;
bool isrightcode=true;
foreach(string err in this.errorcodes.keys)
{
if(statuscode==err)
{
isexist=true;
isrightcode=false;
break;
}
}
foreach(string right in this.rightcodes.keys)
{
if(statuscode==right)
{
isexist=true;
break;
}
}
//根据状态码来处理下一步的动作
if(!isexist) //不是合法的smtp主机
{
this.seterror("不是合法的smtp主机,或服务器拒绝服务");
}
else if(!isrightcode)//命令没能成功执行
{
this.seterror(statuscode+":"+this.errorcodes[statuscode]);
}
else //命令成功执行
{
this.errormessage="";
}
return response;
}
else
{
return null;
}
}
/// <summary>
/// 通过auth login方式登陆smtp服务器
/// </summary>
private void landingbylogin()
{
string base64userid=this.convertbase64string(this.userid,"ascii");
string base64pass=this.convertbase64string(this.password,"ascii");
//握手
this.sendcommand("helo "+this.servername,false);
//开始登陆
this.sendcommand("auth login",false);
this.sendcommand(base64userid,false);
this.sendcommand(base64pass,false);
}
/// <summary>
/// 通过auth plain方式登陆服务器
/// </summary>
private void landingbyplain()
{
string null=((char)0).tostring();
string loginstr=null+this.userid+null+this.password;
string base64loginstr=this.convertbase64string(loginstr,"ascii");
//握手
this.sendcommand("helo "+this.servername,false);
//登陆
this.sendcommand(base64loginstr,false);
}
/// <summary>
/// 通过auth cram-md5方式登陆
/// </summary>
private void landingbycrammd5()
{
//握手
this.sendcommand("helo "+this.servername,false);
//登陆
string response=this.sendcommand("auth cram-md5",false);
//得到服务器返回的标识
string identifier=response.remove(0,4);
//用md5加密标识
ksn_mactripledes mac=new ksn_mactripledes();
mac.key=this.password;
mac.data=encoding.ascii.getbytes(identifier);
string hash=mac.gethashvalue();
//发送用户帐号信息
this.sendcommand(this.userid+" "+hash,false);
}
/// <summary>
/// 发送邮件
/// </summary>
/// <returns></returns>
public bool sendmail(mailmessage mail)
{
bool issended=true;
try
{
//检测发送邮件的必要条件
if(mail.sender==null)
{
this.seterror("没有设置发信人");
}
if(mail.receivers.count==0)
{
this.seterror("至少要有一个收件人");
}
if(this.smtpvalidatetype!=smtpvalidatetypes.none)
{
if(this.userid==null || this.password==null)
{
this.seterror("当前设置需要smtp验证,但是没有给出登陆帐号");
}
}
//开始登陆
switch(this.smtpvalidatetype)
{
case smtpvalidatetypes.none:
this.sendcommand("helo "+this.servername,false);
break;
case smtpvalidatetypes.login:
this.landingbylogin();
break;
case smtpvalidatetypes.plain:
this.landingbyplain();
break;
case smtpvalidatetypes.crammd5:
this.landingbycrammd5();
break;
default:
break;
}
//初始化邮件会话(对应smtp命令mail)
this.sendcommand("mail from:<"+mail.sender+">",false);
//标识收件人(对应smtp命令rcpt)
foreach(string receive in mail.receivers)
{
this.sendcommand("rcpt to:<"+receive+">",false);
}
//标识开始输入邮件内容(data)
this.sendcommand("data",false);
//开始编写邮件内容
string message="subject:"+mail.subject+crlf;
message+="x-mailer:"+mail.xmailer+crlf;
message+="mime-version:1.0"+crlf;
if(mail.attachments.count==0)//没有附件
{
if(mail.mailtype==mailtypes.text) //文本格式
{
message+="content-type:text/plain;"+crlf+" ".padright(8, )+"charset=\""+
mail.mailencoding.tostring()+"\""+crlf;
message+="content-transfer-encoding:base64"+crlf+crlf;
if(mail.mailbody!=null)
message+=convert.tobase64string(mail.mailbody,0,mail.mailbody.length)+crlf+crlf+crlf+"."+crlf;
}
else//html格式
{
message+="content-type:multipart/alertnative;"+crlf+" ".padright(8, )+"boundary"
+"=\"=====003_dragon310083331177_=====\""+crlf+crlf+crlf;
message+="this is a multi-part message in mime format"+crlf+crlf;
message+="--=====003_dragon310083331177_====="+crlf;
message+="content-type:text/html;"+crlf+" ".padright(8, )+"charset=\""+
mail.mailencoding.tostring().tolower()+"\""+crlf;
message+="content-transfer-encoding:base64"+crlf+crlf;
if(mail.mailbody!=null)
message+=convert.tobase64string(mail.mailbody,0,mail.mailbody.length)+crlf+crlf;
message+="--=====003_dragon310083331177_=====--"+crlf+crlf+crlf+"."+crlf;
}
}
else//有附件
{
//处理要在邮件中显示的每个附件的数据
stringcollection attatchmentdatas=new stringcollection();
foreach(string path in mail.attachments)
{
if(!file.exists(path))
{
this.seterror("指定的附件没有找到"+path);
}
else
{
//得到附件的字节流
fileinfo file=new fileinfo(path);
filestream fs=new filestream(path,filemode.open,fileaccess.read);
if(fs.length>(long)int.maxvalue)
{
this.seterror("附件的大小超出了最大限制");
}
byte[] file_b=new byte[(int)fs.length];
fs.read(file_b,0,file_b.length);
fs.close();
string attatchmentmailstr="content-type:application/octet-stream;"+crlf+" ".padright(8, )+"name="+
"\""+file.name+"\""+crlf;
attatchmentmailstr+="content-transfer-encoding:base64"+crlf;
attatchmentmailstr+="content-disposition:attachment;"+crlf+" ".padright(8, )+"filename="+
"\""+file.name+"\""+crlf+crlf;
attatchmentmailstr+=convert.tobase64string(file_b,0,file_b.length)+crlf+crlf;
attatchmentdatas.add(attatchmentmailstr);
}
}
//设置邮件信息
if(mail.mailtype==mailtypes.text) //文本格式
{
message+="content-type:multipart/mixed;"+crlf+" ".padright(8, )+"boundary=\"=====001_dragon320037612222_=====\""
+crlf+crlf;
message+="this is a multi-part message in mime format."+crlf+crlf;
message+="--=====001_dragon320037612222_====="+crlf;
message+="content-type:text/plain;"+crlf+" ".padright(8, )+"charset=\""+mail.mailencoding.tostring().tolower()+"\""+crlf;
message+="content-transfer-encoding:base64"+crlf+crlf;
if(mail.mailbody!=null)
message+=convert.tobase64string(mail.mailbody,0,mail.mailbody.length)+crlf;
foreach(string s in attatchmentdatas)
{
message+="--=====001_dragon320037612222_====="+crlf+s+crlf+crlf;
}
message+="--=====001_dragon320037612222_=====--"+crlf+crlf+crlf+"."+crlf;
}
else
{
message+="content-type:multipart/mixed;"+crlf+" ".padright(8, )+"boundary=\"=====001_dragon255511664284_=====\""
+crlf+crlf;
message+="this is a multi-part message in mime format."+crlf+crlf;
message+="--=====001_dragon255511664284_====="+crlf;
message+="content-type:text/html;"+crlf+" ".padright(8, )+"charset=\""+mail.mailencoding.tostring().tolower()+"\""+crlf;
message+="content-transfer-encoding:base64"+crlf+crlf;
if(mail.mailbody!=null)
message+=convert.tobase64string(mail.mailbody,0,mail.mailbody.length)+crlf+crlf;
for(int i=0;i<attatchmentdatas.count;i++)
{
message+="--=====001_dragon255511664284_====="+crlf+attatchmentdatas[i]+crlf+crlf;
}
message+="--=====001_dragon255511664284_=====--"+crlf+crlf+crlf+"."+crlf;
}
}
//发送邮件数据
this.mailencodingname=mail.mailencoding.tostring();
this.sendcommand(message,true);
if(this.sendiscomplete)
this.sendcommand("quit",false);
}
catch
{
issended=false;
}
finally
{
this.disconnect();
//输出日志文件
if(this.logpath!=null)
{
filestream fs=null;
if(file.exists(this.logpath))
{
fs=new filestream(this.logpath,filemode.append,fileaccess.write);
this.logs=crlf+crlf+this.logs;
}
else
fs=new filestream(this.logpath,filemode.create,fileaccess.write);
byte[] logpath_b=encoding.getencoding("gb2312").getbytes(this.logs);
fs.write(logpath_b,0,logpath_b.length);
fs.close();
}
}
return issended;
}
/// <summary>
/// 异步写入数据
/// </summary>
/// <param name="result"></param>
private void asynccallback(iasyncresult result)
{
if(result.iscompleted)
this.sendiscomplete=true;
}
/// <summary>
/// 关闭连接
/// </summary>
private void disconnect()
{
try
{
ns.close();
tc.close();
}
catch
{
;
}
}
/// <summary>
/// 设置出现错误时的动作
/// </summary>
/// <param name="errorstr"></param>
private void seterror(string errorstr)
{
this.errormessage=errorstr;
logs+=this.errormessage+crlf+"【邮件处理动作中止】"+crlf;
this.disconnect();
throw new applicationexception("");
}
/// <summary>
///将字符串转换为base64
/// </summary>
/// <param name="str"></param>
/// <param name="encodingname"></param>
/// <returns></returns>
private string convertbase64string(string str,string encodingname)
{
byte[] str_b=encoding.getencoding(encodingname).getbytes(str);
return convert.tobase64string(str_b,0,str_b.length);
}
#endregion
}
}



文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·JSP页面中的自定义标签-JSP教程,Jsp/Servlet
·动态加载Asp.net分页控件-.NET教程,Asp.Net开发
·探究客户端浏览器分辨率的自适应问题(2)-.NET教程,评论及其它
·使用Eclipse开发Jsp-JSP教程,Jsp/Servlet
·正确优雅地解决用户退出——JSP及Struts解决方案-JSP教程,Jsp/Servlet
·关于C#中虚方法重载的说明-.NET教程,C#语言
·如何查看本机打开的端口是被哪个程序使用的-网管专栏,操作系统
·C#中来应用Hook-.NET教程,C#语言
·网页表单验证代码的改进-ASP教程,脚本编码
·最新版ccnp教材介绍
最新文章
·号称全球第一篇华人女站长的建站理财文章_站长心得
·衡量一个网站的价值的公平化的标准是什么?_站长心得
·谈谈网站设计的10个要点2_站长心得
·获取google pagerank值的研究_google推广
·强悍的网络编辑是怎样炼成的?_网络编辑
·点析网站发展三阶段3_站长心得
·个人网站真能转成商业网站,你能么?_站长心得
·百度搜索引擎使用指南_baidu推广
·加入自动功能windows vista磁盘整理全面解析_windows vista
·asp.net中多彩下拉框的实现_asp.net技巧
相关主题
  • 用C#写的一个简单屏幕保护程序-.NET教程,C#语言
  • 用c#写的贪吃蛇游戏,简简单单-.NET教程,C#语言
  • 用c#写的asp+域名查询程序
  • 西部数码虚拟主机

    友情链接
    CNNIC 西部数码
    万网 自助建站
    虚拟主机 asp空间
    域名注册 域名
    域名申请 主页空间
    论坛空间 网站空间
    国际域名 虚拟空间
    空间租用 DDOS防火墙
    成都主机托管 四川主机托管
    主机租用 服务器租用
    网站目录 自助建站
    虚拟主机 网址大全
    软件下载
    自助链接
    虚拟主机资讯 特价虚拟主机
    版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
    关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
    发表评论 打印  刷新     关闭