电子邮件系统的设计与实现.docx
- 文档编号:7866748
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:27
- 大小:213.76KB
电子邮件系统的设计与实现.docx
《电子邮件系统的设计与实现.docx》由会员分享,可在线阅读,更多相关《电子邮件系统的设计与实现.docx(27页珍藏版)》请在冰豆网上搜索。
电子邮件系统的设计与实现
第一章前言
1.1课题来源
当前流行的各大邮件客户端软件除了最主要的收发信件之外,功能越来越复杂,但是人们平常真正用到的功能很少,很多功能尤其对于那些计算机知识相对缺乏的人来说,更加显得太过于华丽而不太实用。
有鉴于此,在了解RFC底层协议的基础上,本人开发了这个各种功能相对简单实用的邮件客户端程序,简化了很多不必要的功能。
1.2电子邮件介绍
电子邮件(简称E-mail)又称电子信箱、电子邮政,它是一种用电子手段提供信息交换的通信方式。
它是全球多种网络上使用最普遍的一项服务。
这种非交互式的通信,加速了信息的交流及数据传送,它是一个简易、快速的方法。
通过连接全世界的Internet,实现各类信号的传送、接收、存储等处理,将邮件送到世界的各个角落。
到目前为止,可以说电子邮件是Internet资源使用最多的一种服务,E-mail不只局限于信件的传递,还可用来传递文件、声音及图形、图像等不同类型的信息。
电子邮件不是一种“终端到终端”的服务,是被称为“存储转发式”服务。
这正是电子信箱系统的核心,利用存储转发可进行非实用时通信,属异步通信方式。
即信件发送者可随时随地发送邮件,不要求接收者同时在场,即使对方现在不在,仍可将邮件读取信件,不受时空限制。
在这里,“发送”邮件意味着将邮件放到收件人的信箱中,而“接收”邮件则意味着从自己的信箱中读取信件,信箱实际上是由文件管理系统支持是一个实体。
因为电子邮件是通过邮件服务器(mail server)来传递的。
通常mail server 是执行多任务操作系统UNIX的计算机,它提供24小时的电子邮件服务,用户只要向mail server管理人员申请一个信箱账号,就可使用这项快递的邮件服务。
1.3电子邮件的工作原理:
电子邮件的发送是通过电子邮件简单传速协议(Simple Mail Transfer Protocol,简称SMTP)来完成的,电子邮件的接受是通过POP3协议来实现。
它是Internet下的一种电子邮件通信协议。
电子邮件的基本原理,是在通信网上设立“电子信箱系统”,它实际上是一个计算机系统。
系统的硬件是一个高性能、大容量的计算机。
硬盘作为信箱的存储介质,在硬盘上为用户分一定的存储空间作为用户的“信箱”,每位用户都有属于自己的一个电子信箱。
并确定一个用户和用户可以随意修改的口令。
存储空间包含存放所收信件、编辑信件以及信件存盘三部分空间,用户使用口令开启自己的信箱,并进行发信、读信、编辑、转发、存档等各种操作。
系统功能主要由软件实现。
1.4开发环境及运行环境
1.4.1开发环境
AMD Athlom(TM), 512 内存,80G 硬盘
Microsoft(R)Windows XP Professional
Micosoft Visual Studio 2003 (C Sharp)
Micosoft Developer Network for Visual Studio.NET 2003
1.4.2运行环境
Internet pentium 2及以上处理器,32M以上内存,4G以上硬盘
Micosoft windows 9X/NT操作系统
800*600或以上的屏幕分辨率
确保机器上安装有.Net FrameWork 1.0或者以上版本
第二章系统需求分析
2.1系统功能需求分析
电子邮件系统需求实现的功能包括新建用户的帐号,接受简单邮件或带附件的邮件,发送简单邮件或发送带附件的邮件,电子邮件编号,电子邮件分类管理,通信薄管理。
为了使用通信薄,于是添加了对用户资料的增加,修改,取消操作。
2.1.1软件的总体架构
图1软件构架图
2.1.2系统功能
图2系统功能图
2.1.3系统总体用例图
图3系统总体用例图
2.2数据库需求分析
在对系统进行系统需求分析的基础上,可以得到系统在处理数据时会用到下面所示的数据项和数据结构:
1)用户信息:
帐号名称,用户名,密码,电子邮箱地址,SMTP服务器,SMTP端口号,POP3服务器,POP3端口号。
2)通信薄信息:
姓名,邮箱地址,电话号码,QQ号,手机号码,通信地址。
第三章系统设计
3.1系统的流程设计
邮件客户端最重要的两个功能就是接收邮件和发送邮件,其中接收邮件的流程图如图4所示。
从流程图中可以看出,接收邮件时首先要创建一个TCP连接到POP3服务器。
如果连接不成功就退出执行,连接成功后再发送USER和PASS命令进行身份验证,身份验证通过后再通过STAT命令获得要接收的邮件数,当邮件数大于0时,通过RETR命令逐个接收邮件。
接收邮件完毕后,检查帐号中是否保留服务器上的邮件设置,如果是就不作任何操作,否则从服务器上删除已经接受的邮件。
最后关闭连接。
完成邮件接收。
图4接收邮件流程图
发送邮件的流程图,先检查“发信箱”目录中是否有待发邮件,如果有就逐个发送这些邮件,流程图如图5所示。
其发送过程,首先需要创建一个TCP连接,连接到SMTP服务器,如果连接不成功就退出程序。
连接成功后发送USER和PASS命令进行身份验证。
身份验证通过后发送邮件,如果发送成功就关闭连接,更新数据库,完成邮件发送任务。
图5发送邮件流程图
3.2SMTP协议的研究
由于要开发的是邮件客服端程序,就不得不用到SMTP协议和POP协议。
而我个人负责
的是邮件发送功能的实现,因此就必然会涉及到SMTP(Simple Mail Transfer Protocol)协议。
SMTP被用来在因特网上发送邮件,该协议规定了一些基本的命令和方法使客服端与服务器进行交互,以达到发送邮件的目的。
3.2.1SMTP介绍
简单邮件传输协议(SMTP)的目标是可靠高效地传送邮件,它独立于传送子系统而且仅要求一条可以保证传送数据单元顺序的通道。
SMTP的一个重要特点是它能够在传送中接力传送邮件,传送服务器提供了进程间通信环境(IPCE),此环境可以包括一个网络,几个网络或一个网络的子网。
理解到传输送系统(或IPCE)不是一对一的是很重要的。
进程可能直接和其它进程通过已知的IPCE通信。
邮件是一个应用程序或进程间通信。
邮件可以通过连接在不同IPCE上的进程跨网络进行邮件传送。
更特别是,邮件可以通过不同网络上的主机接力式传送。
3.2.2SMTP模型
SMTP设计基于以上通信模型:
针对用户的邮件请求,发送SMTP建立于接收SMTP
之间建立一个双向传送通道。
接收SMTP可以是最终接收者也可以是中间传送者。
SMTP命令由发送SMTP发出,由接收SMTP接收,而应答则反方面传送。
一旦传送通道建立,SMTP发送者发送MAIL命令指明邮件发送者。
如果SMTP接收者可以接收邮件则返回OK应答。
SMTP发送者再发出RCRT命令确认邮件是否接收到。
如果SMTP接收者接收,则返回OK应答;如果不能接收到,则发出拒绝接收应答(但不中止整个邮件操作),双方将如此重复多次。
当接收者到全部邮件后会接收到特别的序列,如果接收者成功处理了邮件,则返回OK应答。
SMTP提供传送邮件的机制,如果接收方与发送方连接在同一个传送服务下时,邮件可以直接由发送方主机传送到接收方主机;或者,当两者在不同一个传送服务下时,通过中继SMTP服务器传送。
为了能够对SMTP服务器提供中继能力,它必须拥有最终目的主机地址和邮箱名称。
MAIL命令参数是回复路径,它指定邮件从何处来;而RCPT命令的参数是转发路径的,它指定邮件向何处去。
向前路径是源路径,而回复路径是返回路径(它用于发生错误时返回邮件)。
当同一个消息要发往不同的接收者时,SMTP遇到了向不同接收者发送同一份数据的复制品的问题,邮件命令和应答有一个比较奇怪的语法,应答也有一个数字代码。
在下面,例子中可以看到哪些使用实际的命令和应答。
完整的命令和应答在第四节。
命令与应答对大小写不敏感,也就是说,命令和应答可以是大写,小写或两者的混合,但这一点对用户邮件名称却不一定是对的,因为有的主机对用户名大小写是敏感的。
这样SMTP实现中就将用户邮箱名称保留成初始时的样子,主机名称对大小写不敏感。
命令与应答由ASCII字母表组成,当传送服务提供8位子节传送通道,每7位字符正确传送,而最高位被填充为0。
当指定一般的命令或应答格式后,参数会由一些类似于语言的字符串表示出来,如“
3.3SMTP协议的命令和应答
3.3.1SMTP协议的命令
SMTP命令定义了邮件传输或用户定义的系统功能。
它的命令是由
而在带有参数的情况下,命令本身由
邮箱的语法格式必须和接收站点的格式一致。
3.3.2SMTP的应答码
对SMTP命令的响应是多样的,它确定了在邮件传输过程中请求和处理的同步,也保证了发送SMTP知道接收SMTP的状态。
每个命令必须有且只有一个响应。
SMTP响应由三位数字组成,其后跟一些文本。
数字帮助决定下一个应该进入的状态,而文本对人是有意义的。
三位的响应已经包括了足够的信息,不用再阅读文本,文本可以直接抛弃或者传递给用户。
特别的是,文本是与接收和环境相关的,所以每次接收到的文本可能不同。
正规的情况下,响应由下面序列构成:
三位的数字,
只有EXPN和HELP,命令可以导致多行应答,然而,对所有命令,多行响应都是允许的。
REPLYCODESBYFUNCTIONGROUPS500格式错误,命令不可识别(此错误也包括命令行过长)
第四章RFC822
说到发送和接收邮件,就不得不提RFC822了。
RFC822的全称是“ARPA因特网文信件格式的标准”(StandardfortheFormatofARPAInternetTextMessages)。
该标准提供了邮件内容的格式和相关语义。
4.1RFC822简单介绍
RFC822规定的电子邮件内容全部由ASCII字符组成,就是通常所说的文本文件,因而标准将它称为Internet文本信件(InternetTextMessages)。
从直观上看,信件非常简单,就是一系列由ASCII字符组成的文本行,每一行以回车换形符结束。
从组织上看,信件内容结构分为两大部分,中间用一个空白行(只有CRLF符的行)来分隔。
第一部分称为信件的头部,包括有关发送方、接收方、发送日期等信息。
第二部分称为信件的体部,包括信件内容的正文文体。
信头是必需的,信体是可选的,即信体可有可无。
如果不存在信体,用作分隔的空白行也就不需要。
在信体中,也可以有用作分隔的空白行。
这样设计的信件便于进行语法分析,提取信件的基本信息。
在RFC822中规定,信件体就是一系列的向收信人表达信息的文本行,比较简单,可以包括任意文本。
并没有附加的结构。
信件头则具有比较复杂的结构,在下一小节中详述。
4.2信件的头部
4.2.1信头一般格式
信头的结构比较复杂,信头由若干信头字段(headerfield)组成,这些字段为用户和程序提供了关于信件的信息。
要了解信头的结构就要弄清楚各种信头字段。
所有的信头字段都具有相同的语法结构,从逻辑上说,包括四部分,字段名(fieldname)紧跟冒号“:
”(colon),后跟字段体(fieldbody),最后以回车换形符(CRLF)终止。
即
信头字段=字段名:
字段体CRLF
字段名必须由除了冒号和空格以外的可打印US—ASCII字符(其值在33和126之间)组成,大多数字段的字段名称由一系列字母,数字组成,中间经常插入横线符。
字段名告诉电子邮件软件如何翻译该行中剩下的内容。
字段体可以包括除了CR和LF之外的任何ASCII字符。
但是其中的格式的空格,加括号的注释,引号和多行都比较复杂,另外,字段体的语法和语义依赖于字段名,每个类型的字段有特定的格式。
4.2.2结构化字段和非结构化字段
每个字段包含的信息不同,字段大体可以分为结构化字段和非结构化字段。
结构化字段有特定的格式,由语法分析程序检测。
Sender字段就是一个很好的例子,它的字段内容是信箱,有一个离散的结构。
非结构化的字段含有任意的数据,没有固定格式。
例如,Subject字段可以含有任意的文字,并且没有固定格式。
非结构化的字段数量较少,只有Subject、Comments、扩展字段、非标准字段、IN—Reply和References等。
所有其它字段都是结构化的。
4.2.3信头字段的元素
尽管Email信件的总体结构非常简单,但一些信头字段的结构是很复杂的。
下面介绍一些大多数字段共有的元素。
(1)空白符
像其它文本文件一样,空白符包括空格符(ASCII码32)和制表符TAB(ASCII码19)此外,行末的回车换形符CRLF也应算是空白符。
使用空白符可以对字段进行格式化,增加它的可续性。
例如,每个字段间用CRLF来分离,在字段内用空格来分隔字段名和字段内容。
在Subject后面的冒号和内容之间插入空格字符,会使字段结构更加清晰。
在Email中。
空白符的使用并没有固定的规则,但应当正确地使用,仅在需要时才使用空白符,以便接收软件进行语法分析。
(2)注解
注解是由括号括起来的一系列字符,例如,(这份礼物)。
注解一般用在非结构化的信头字段中,没有语法语义,仅为人提供了一些附加的信息。
如果在加引号的字符串中包括在括号中的字符,那是字符串的一部分,不是注解。
在解释信件的时候,会将注解忽略,可以用一个空格字符代替它们,这样就什么也不会破坏。
(3)字段折叠
每个信头字段从逻辑上说应当是一个由字段名、冒号、字段体和CRLF组成的单一的行,但为了书写与显示的方便,增加可续行,也为了符号1000/80的行字符数的限制,可以将超过80个字符的信头字段分为多行,即对于比较长的字段,可以分割成几行,形成折叠。
在结果化和非结构化字段中都允许折叠,第一行后面的行称为信头字段的续行。
续行都以一个空白符开始,这种方法称为折叠(folding),例如标题字段Subject:
Thisisatest可以表示为:
Subject:
Thisisatest
反之,将一个被折叠成多行的信头字段恢复到它的单行表示的过程叫做去折叠,只要简单地移除后面跟着空格的CRLF,将折叠空白符CRLF转换成空格字符,就可以完成折叠。
在分析被折叠的字段的语法时,要把一个多行的折叠字段展开为一行,根据它的非折叠的形式来分析它的语法与语义。
(4)字段大小写
字段名称是不区分大小写的,所以Subject、subject或SUBJECT都一样。
不过字段名称大小写有习惯的常用形式,如主题字段的大小写形式通常为Subject。
字段体的大小写稍微复杂点,要视情况而定。
比如Subject后面的字段体,其中的大写可能就是缩写的专用名词,不能改动。
(5)扩展字段
如果想在信头中加入RFC822中没有规定的字段,就需要创建非标准字段。
方法非常简单,只要在自定义的信头字段名的前面使用X-前缀。
RFC822将这种方法称为扩展字段。
事实上已经有许多扩展字段被广泛应用,但没有标准定义。
例如:
X—LOOP字段
X—LOOP字段用来防止邮件的循环传送。
过滤或邮件列表处理程序,可以给它处理的每个信件增加一个X—LOOP字段,以后就可以根据这个字段中含有的特别值,判断一个信件是否被循环传送。
如果确认邮件发生了循环,过滤或邮件列表处理程序就可以用不同的方式处理该信件。
◆X—Mailer字段
X—Mailer字段用于指示什么样的程序产生了这个信件,它是使用最广泛的扩展字段。
产生邮件的软件可以为所有发送的信件增加合适的X—Mailer字段,该字段不仅含有软件的名称,还包含软件的版本号。
例如软件名为LittlefoxMailer,版本为V1.0,可以将“X—Mailer:
LittlefoxMailerV1.0”加到邮件信头中去。
图6列出了一些在因特网电子邮件可以找到的普通关键字,以及使用它们的目的。
关键字含义
From发送方地址
TO接收方地址
Cc复制副本地址
Date信息创建日期
Subject信息主题
Reply—To回复地址
X—Charset使用的字符集(通常为ASCII)
X—Mailer发送信息所使用的软件
X—Sender发送方地址的副本
X—Face经编码的发送方面孔的图像
整个系统的核心是收发信件的操作,因此为了方便维护,以后的升级,故将这两个最主要的操作写成类库(.dll)的形式,以组件的形式加载到主程序中,而且其它的功能如果需要的话,也可以通过这样的组件的形式增加到主程序中。
这也体现了CSharp这一新的微软主推语言的方便和高效。
而且这样做也方便了我们小组的程序的顺利结合。
第五章系统实现
5.1发送邮件类
SmtpMail是发送邮件的核心,类名为SmtpMail,隶属于命名空间MailSend。
封装了发送邮件的具体实现方法,也是具体的RFC用代码实现的过程。
而用户通过具体的操作接口,接收与SmtpMail类通过交互操作来实现用户发送信件的操作。
5.1.1主要成员变量说明
1)网络连接类及实例TcpClienttc
为TCP网络服务提供客户端连接类TcpClient实例对象tc。
TcpClient类提供了一些简单的方法,用于在同步阻塞模式下通过网络来连接、发送和接收流数据。
而实例化的过程也是连接SMTP服务器的过程。
它的重载方法之一的两个参数一个为服务器名称字符串,另一个为服务器的埠。
2)提供用于网络访问的基础数据流及其实例NetworkStreamns
此类提供访问网络的基础数据流的方法。
其中最基本也是最重要的两个方法就是Write()和Read()方法,至于参数不再次描述。
3)一维字符串数组变量FilePath
此字符串数组主要用来存放用户选择的附件的绝对路径名,并在发送带附件的邮件时用到。
4)发送邮件所需的基本参数
比如用于ESMTP登录检验用的用户名、密码,发送邮件需要的收信人,发信人地址以及主题等等在此不再陈述。
5.1.2主要成员函数说明
1)重载的构造函数SmtpMail()
此函数主要用于在初始化过程中,把用户选择的附件的路径以参数的形式传给FilePath。
2)添加附件的函数AddAttachment
传给FilePath的路径,通过这样一个函数就可以循环的动态的添加到LIST接口的一个对象中了,方便以后在具体的实现过程中使用。
3)得到上传的附件的文件流GetStream
由于在网络中的操作都是以网络流的形式来实现的,因此先将上传的附件转换成文件流,然后再用Write的方法把这些附件的文件流写入到网络中,来完成发送附件的操作。
具体实现代码如下所示:
///
///得到上传附件的文件流
///
///
PrivatestringGetStream(stringFilePath)
{
Try
{
//新建文件流对象
System.IO.FileStreamFileStr=newSystem.IO.FileStream(FilePath,
System.IO.FileMode.Open);
Byte[]by=newbyte[System.Convert.ToInt32(FileStr.Length)];
FileStr.Read(by,0,by.Length);
FileStr.Close();
Return(System.Convert.ToBase64String(by));
}
Catch
{
MessageBox.Show(“可能你要打开的文件的属性是只读的!
”,“请检查权限”);
Returnnull;
}
}
4)将字符串编码为Base64字符串的函数Base64Encode
由于ESMTP的LOGIN认证机制是采用Base64编码,当用户发出AUTHLOGIN的命令后,服务器返回334的应答码等待用户输入。
如果身份确认后服务器返回235的应答码,否则返回失败信息。
所以要将用户名和密码转换Base64编码然后再发给服务器。
此函数的作用就是把给定的字符串转换成相应的Base64编码的字符串。
5)发送SMTP命令的函数
SendCommand的函数作用是把SMTP命令的字符串转换成对应的字节型值(C#中规定的Write方法只能写入字节型的数据)然后写入网络中,如果操作成功就返回一个标志为真的布尔型变量,如果操作失败或者发生异常就返回标志为假的布尔型变量。
具体代码如下所示:
///
///发送SMTP命令
///
privateboolSendCommand(stringstr)
{
Byte[]WriteBuffer;
If(str==null||str.Trim==String.Empty)
{
returntrue;
}
WriteBuffer=Encoding.Default.GetBytes(str);
try
{
ns.Write(WriteBuffer,0,WriteBuffer.Length);
}
Catch
{
Errmsg=”网络链接错误”;
Returnfalse;
}
returntrue;
}
6)接受服务器应答的函数RecvResponse
它的作用就是从网络流中读取服务器返回的字节型的信息,将其转换成字符串型的变量,然后将其返回,可以通过其返回值来判断操作是否成功。
具体实现代码如下所示:
///
///接受SMTP服务器回应
///
privatestringRecvResponse()
{
intStreamSize;
stringReturnValue=string.Empty;
byte[]ReadBuffer=newbyte[1024];
try
{
StreamSize=ns.Read(ReadBuffer,0,ReadBuffer.Length);
}
catch(Exceptionex)
{
MessageBox.Show(ex.ToString());
return“false”;
}
if(StreamSize==0)
{
returnReturnValue;
}
else
{
ReturnValue=Encoding.Default.GetString(ReadBuffer).Substring(0,StreamSize);
returnReturnValue;
}
}
7)重载的函数Dialog
它们的作用是与服务器交互,发送命令并接收回应。
不同的是参数是字符串类型的那个函数,每个发送一条命令,并接受服务器的响应,根据响应的信息来判断交互的结果是否成功。
而参数是字符串数组的函数每次发送的是一组命令,用于和服务器的交互,这个函数主要是用于ESMTP服务器的验证的功能,因为验证的过程是一个等待然后又输入的过程,因此将它们放在一个数组中
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 电子邮件 系统 设计 实现