1、 基于Web Server程序设计 题 目 邮件发送程序设计与实现 学生姓名 边阳 学 号 20090334007 院 系 电子工程系 专 业 通信工程指导教师 高超 二一 二 年 十二月 十八日 邮件发送程序设计与实现 边阳 摘 要 本程序是在了解RFC底层协议的SMTP协议和POP协议基础上,通过C#编程从SMTP协议规定的底层命令做起一步步的与服务器进行交互操作,最终实现发送多邮件功能其中,具体的和服务器的交互操作,都封装了在SmtpMail.dll这个动态链接库里面了。关键词 C#;SMTP;RFC;邮件;POP1前 言电子邮件(简称E-mai1)又称电子信箱、电子邮政,它是种用电子手
2、段提供信息交换的通信方式。它是全球多种网络上使用最普遍的一项服务。这种非交互式的通信,加速了信息的交流及数据传送,它是个简易、快速的方法。通过连接全世界的Internet,实现各类信号的传送、接收、存贮等处理,将邮件送到世界的各个角落。到目前为止,可以说电子邮件是Internet资源使用最多的一种服务,E-mai1不只局限于信件的传递,还可用来传递文件、声音及图形、图像等不同类型的信息。电子邮件不是一种“终端到终端”的服务,是被称为“存贮转发式”服务。这正是电子信箱系统的核心,利用存贮转发可进行非实时通信,属异步通信方式。即信件发送者可随时随地发送邮件,不要求接收者同时在场,即使对方现在不在,
3、仍可将邮件立刻送到对方的信箱内,且存储在对方的电子邮箱中。接收者可在他认为方便的时候读取信件,不受时空限制。在这里,“发送”邮件意味着将邮件放到收件人的信箱中,而“接收”邮件则意味着从自己的信箱中读取信件,信箱实际上是由文件管理系统支持的个实体。因为电子邮件是通过邮件服务器(mai1 server)来传递档的。通常mail server是执行多任务操作系统UNIX的计算机,它提供24小时的电子邮件服务,用户只要向 mail server管理人员申请个信箱账号,就可使用这项快速的邮件服务。1.1课程设计的内容 运用C#语言设计一个邮件程序实现邮件发送1.2课程设计的要求(1)按要求编写课程设计报
4、告书,能正确阐述设计结果。(2)通过课程设计培养学生严谨的科学态度,认真的工作作风和团队协作精神。(3)学会文献检索的基本方法和综合运用文献的能力。(4)在老师的指导下,要求每个学生独立完成课程设计的全部内容。1.3开发环境处理器:Intel(R) Pentium(R) M 786MHz 2.13GHz硬盘空间:160GB内存:1GB显示器:8600GT2 设计平台简介C#编程环境简介20世纪80年代以来,C/C+语言一直是使用最广泛的商业化开发语言。但在带来强大控制能力和高度灵敏性的同时,其代价是相对较长的学习周期和较低下的开发效率,同时对控制能力的滥用也给程序的安全性带来了潜在的威胁。C+
5、语言过度的功能扩张也破坏了面向对象的设计理念。因此,软件行业迫切需要一种全新的现代程序设计语言,他能够在控制能力与生产效率之间达到良好的平衡,特别是将高端应用开发与底层平台访问紧密结合在一起,并与Web标准保持同步,C#(读作C-Sharp)语言就是这一使命的承担着。C#语言是从C/C+语言发展而来的,他汲取了包括C+、Java、Delphi在内的多种语言精华,是一种简单易学、类型安全和完全面向对象的高级程序设计语言。它的设计目标就是在继承C/C+强大功能的用时,兼有RAD(快速应用程序开发)语言的高效性。作为.NET的核心编程语言,c#充分享受了CLR所提供的优势,能够与其他应用程序方便的集
6、成和交互。下面是对它几个突出特点的描述。语法简洁:C#取消了指针、也不定义繁琐的伪关键字;它使用有限地指令、修饰符合操作符,语法上几乎不存在任何冗余,整个语言结构十分清晰。初学者通常能够快速掌握C#基本特性,而C/C+程序员转入C#则几乎不会有什么障碍。完全面向对象:C#具有面向对象的语言所应有的基本特性:封装、继承和多态性。它禁止多继承,禁止各种全局方法、全局变量和常量。C#以类为基础来构建所有的类型,并通过命名空间对代码进行层次化的组织和管理。许多精巧的对象设计模式都在C#语言中得到了有效的应用。与Web紧密结合:借助Web服务框架,C#使得网络开发和本地开发几乎一样简单。开发人员无需了解
7、网络的细节,可以用统一的方式来处理本地的和远程的C#对象,而C#组件能够方便的转为Web服务,并被其他平台上的各种编程语言调用。目标软件的安全性:C#符合通用类型系统的类型安全性要求,并用CLR所提供的代码访问安全特性,从而能够在程序中方便的配置安全等级和用户权限。此外,垃圾收集机制自动管理对象的生命周期,这是的开发人员无需再负担内存管理的任务,应用程序的可靠性进一步得到提高。版本管理技术:C#语言中内置了版本控制功能,并通过接口和继承来实现应用的可扩展性。应用程序的维护和升级更加易于管理。灵活性与兼容性:C#中允许使用非托管代码来与其他程序(包括COM组件、WIN32API等)进行集成和交互
8、。它还可以通过委托(delegate)来模拟织针的功能,通过接口来模拟多继承的实现。 3设计原理基本原理3.1软件总体架构总体架构如图3.1: 图3.1软件总架构3.2软件总体用例图3.2软件总体用例3.3程序功能框架图 程序功能框架图3.33.4发送邮件类是发送邮件的核心,类名为SmtpMail,隶属于命名空间MailSend。封装了发送邮件的具体实现方法,也是具体的RFC用代码实现的过程。而用户通过具体的操作接口,接口与SmtpMail类通过交互操作来实现用户发送信件的操作。3.5附加小功能类是获取一些诸如系统时间,当前用户名,以及本机IP之类的类,类名为AddExtra,隶属于命名空间M
9、ailSend。3.6 SMTP协议研究由于要开发的是邮件客户端程序,就不得不用到SMTP协议和POP协议。而我个人负责的是邮件发送功能的实现,因此就必然会涉及到SMTP(Simple Mail Transfer Protocol)协议。SMTP被用来在因特网上发送邮件,该协议规定了一些基本的命令和方法使客户端与服务器进行交互,以达到发送邮件的目的。36.1 SMTP协议简介及工作原理简单邮件传输协议(SMTP)的目标是可靠高效地传送邮件,它独立于传送子系统而且仅要求一条可以保证传送数据单元顺序的通道。SMTP的一个重要特点是它能够在传送中接力传送邮件,传送服务提供了进程间通信环境(IPCE)
10、,此环境可以包括一个网络,几个网络或一个网络的子网。理解到传送系统(或IPCE)不是一对一的是很重要的。进程可能直接和其它进程通过已知的IPCE通信。邮件是一个应用程序或进程间通信。邮件可以通过连接在不同IPCE上的进程跨网络进行邮件传送。更特别的是,邮件可以通过不同网络上的主机接力式传送。3.6.2 SMTP模型基于以下通信模型:针对用户的邮件请求,发送SMTP建立与接收SMTP之间建立一个双向传送通道。接收SMTP可以是最终接收者也可以是中间传送者。SMTP命令由发送SMTP发出,由接收SMTP接收,而应答则反方面传送。一旦传送通道建立,SMTP发送者发送MAIL命令指明邮件发送者。如果S
11、MTP接收者可以接收邮件则返回OK应答。SMTP发送者再发出RCPT命令确认邮件是否接收到。如果SMTP接收者接收,则返回OK应答;如果不能接收到,则发出拒绝接收应答(但不中止整个邮件操作),双方将如此重复多次。当接收者收到全部邮件后会接收到特别的序列,如果接收者成功处理了邮件,则返回OK应答。SMTP提供传送邮件的机制,如果接收方与发送方连接在同一个传送服务下时,邮件可以直接由发送方主机传送到接收方主机;或者,当两者不在同一个传送服务下时,通过中继SMTP服务器传送。为了能够对SMTP服务器提供中继能力,它必须拥有最终目的主机地址和邮箱名称。MAIL命令参数是回复路径,它指定邮件从何处来;而
12、RCPT命令的参数是转发路径的,它指定邮件向何处去。向前路径是源路径,而回复路径是返回路径(它用于发生错误时返回邮件)。当同一个消息要发往不同的接收者时,SMTP遇到了向不同接收者发送同一份数据的复制品的问题,邮件命令和应答有一个比较奇怪的语法,应答也有一个数字代码。在下面,例子中可以看到哪些使用实际的命令和应答。完整的命令和应答在第四节。命令与应答对大小写不敏感,也就是说,命令和应答可以是大写,小写或两者的混合,但这一点对用户邮件名称却不一定是对的,因为有的主机对用户名大小写是敏感的。这样SMTP实现中就将用户邮箱名称保留成初始时的样子,主机名称对大小写不敏感。命令与应答由ASCII字母表组
13、成,当传送服务提供8位字节传送通道,每7位字符正确传送,而最高位被填充为0。当指定一般的命令或应答格式后,参数会由一些类似于语言的字符串表示出来,如或,这里尖括号表示这是一种类似于语言的变量。4 课程设计步骤4.1函数构造1重载的构造函数 SmtpMail()此函数主要用于在初始化过程中,把用户选择的附件的路径以参数的形式传给FilePath。2添加附件的函数AddAttachment传给FilePath的路径,通过这样一个函数就可以循环的动态的添加到IList接口的一个对象中了,方便以后在具体的实现的过程中的使用。3得到上传的附件的文件流GetStream由于在网络中的操作都是以网络流的形式
14、来实现的,因此先将上传的附件转换成文件流,然后再用Write的方法把这些附件的文件流写入到网络中,来完成发送附件的操作。4将字符串编码为Base64字符串的函数Base64Encode由于ESMTP的LOGIN认证机制是采用Base64编码,当用户发出AUTHLOGIN的命令后,服务器返回334的应答码等待用户输入。如果身份确认后服务器返回235的应答码,否则返回失败信息。所以要将用户名和密码转换成Base64编码然后再发给服务器。此函数的作用就是把给定的字符串转换成相应的Base64编码的字符串。5发送SMTP命令的函数SendCommand这个函数的作用是把SMTP命令的字符串转换成对应的
15、字节型值(C中规定的Write方法只能写入字节型的数据)然后写入网络中,如果操作成功就返回一个标志为真的布尔型变量,如果操作失败或者发生异常就返回标志为假的布尔型变量。7重载的函数 Dialog它们的作用是与服务器交互,发送命令并接收回应。不同的是参数是字符串类型的那个函数,每次发送一条命令,并接受服务器的响应,根据响应的信息来判断交互的结果是否成功。而参数是字符串数组的函数每次发送的是一组命令,用于和服务器的交互,这个函数主要是用于ESMTP服务器的验证的功能,因为验证的过程是一个等待然后又输入的过程,因此将他们放在一个数组中有利于理解和操作。而他们的实现主要是通过调用上面的发送SMTP命令
16、函数SendCommand以及接受SMTP服务器响应的函数RecvResponse来实现的。8邮件发送程序SendMail这是整个程序的核心部分。具体的实现SMTP协议的程序正是通过它一步一步实现并最终实现发送简单邮件甚至带附件的邮件的功能。而它的实现是调用以上给出的各个函数的结果。以下就简单的通过几个SMTP命令的格式来实现4.2 Addextra类这个附加的小类只是提供一些返回当前系统时间,获取主机名,主机IP,有关帮助等小的功能,在此仅对帮助信息中的“关于”操作函数稍加说明。因为它说明了在C Sharp 中调用 Windows API 函数所需如下几个步骤:4.2.1调用Windows
17、API 所需的命名空间-using System.Runtime.InteropServices;而调用显示关于对话框的函数ShellAbout还需要用到两个命名空间如下所示-using System.Reflection;-using System.Diagnostics ;4.2.2在程序中声明所需的API函数DllImport(shell32.dll)static extern int ShellAbout(IntPtr hWnd, string szApp, string szOtherStuff,IntPtr hIcon);4.2.3具体的使用Assembly ass=Assembl
18、y.GetExecutingAssembly();FileVersionInfo myVersion=FileVersionInfo.GetVersionInfo(ass.Location );ShellAbout(this.Handle ,邮件收发系统#,版本+myVersion.FileMajorPart +.+myVersion.FileMinorPart+. +myVersion.CompanyName ,this.Icon .Handle );至此就完成了在C Sharp中调用 Windows API 函数的过程5测试5.1测试目的检测邮件发送程序是否能发送邮件5.2测试环境WIND
19、OW XP5.3调试结果邮件发送出去之后,用FoxMail跟踪接收之后,证明邮件和附件都可以正常接收,具体的FoxMail的接收界面如下所示: 图5.1验证邮件发送是否成功5.4结果分析邮件发送成功本程序实现邮件发送功能 参 考 文 献 1 Simon Robinson, K.Scott Allen等.C#高级编程. 北京:清华大学出版社,2002,3 2 Tom Archer. C#技术内幕. 北京:清华大学出版社,2002,1 3沉舟.Microsoft.NET编程语言C#. 北京:希望电子出版社2001,3 4 宋文官,胡荣,许文商务网站规划与管理清华大学出版社2004 5 徐远超网络实践指导教程清华大学出版社2009 6 郭放,陈光现代通信网络应用实践水利水电出版社2009