电子邮件收发系统设计Word格式.doc
《电子邮件收发系统设计Word格式.doc》由会员分享,可在线阅读,更多相关《电子邮件收发系统设计Word格式.doc(42页珍藏版)》请在冰点文库上搜索。
电子邮件使人们的交流方式得到了极大的改变.人们平时所发送或接收的电子邮件,并不是由本机来实现SMTP协议与POP3协议,电子邮件内容全是存储在相应服务商的POP3服务器上,用户必须要登录到相应的服务器上才能进行浏览、查询或者删除操作,但是,在网络繁忙或大家集中传输数据的时候,人们可能收不到消息或者打开很慢.为了解决这一难题,我们开发了电子邮件收发系统,将邮件服务器上的内容保存到本地机器上,这样即使在网络断开的情况下,也能查询已存在本地机器上的邮件。
第2章需求分析
2.1产品可行性分析
整个电子邮件系统由电子邮件服务器端和电子邮件客户端组成,其工作过程及一些涉及到的协议如图2.1所示:
图2.1电子邮件系统工作过程图
其中SMTP是因特网电子邮件系统重要的应用层协议。
它使用由TCP提供的可靠的数据传输服务把邮件消息从发信人邮箱所在邮件服务器传送到收信人邮箱所在邮件服务器。
SMTP是客户-服务器应用模式,由发信人的邮件服务器执行的客户端和收信人的邮件服务器执行的服务器端组成。
SMTP的客户端和服务器端同时运行在每个邮件服务器上。
当一个邮件服务器向其它邮件服务器发送邮件消息时,它是作为SMTP客户端。
当一个邮件服务器从其它邮件服务器接收邮件消息时,它是作为SMTP服务器端。
SMTP规范定义在RFC821中,它的作用是把邮件消息从发信人的邮件服务器传送到收信人的邮件服务器。
SMTP限制所有邮件消息的信体必须是简单的7位ASCII字符格式。
这个限制使得二进制多媒体数据在由SMTP传送之前必须编码成7位ASCII文本;
SMTP传送完毕之后,再把相应的7位ASCII文本邮件消息解码成二进制数据。
POP3是RFC1939中定义的一个简单的邮件访问协议,其功能有限。
POP3开始于用户代理打开一个到POP3服务器端口号110的TCP连接。
POP3服务器与邮件服务器运行在相同的服务器主机上,前者从用户的邮箱中读取并可能删除邮件消息,后者往用户的邮箱中写入邮件消息。
TCP连接建立好之后,POP3依次经历授权认证、处理和更新3个阶段。
在授权阶段,用户代理分别发出一个用户名和一个口令以认证下载邮件消息的用户。
在处理阶段,用户代理获取邮件消息,并可以标记待删除的邮件消息或去掉这些标记,获取邮件统计信息。
更新阶段发生在用户代理发出quit命令以结束当前POP3会话之后,期间POP3服务器删除己加过删除标记的邮件消息。
在POP3会话期间,用户代理发出命令,POP3服务器则对每个命令响应以一个应答。
可能的应答有两个:
指出刚才的命令执行成功的+OK(有时后跟一个解释性消息)和指出刚才的命令执行有误的-ERR。
一个邮件的收发就是通过SMTP传递消息到对端邮件服务器,对端客户使用POP3协议从服务器上获得邮件的过程。
在本设计中,采用自己编写基于socket的方法,来解析协议,进行邮件收发。
同时,在进行邮件收发,需要提供基于BASE64加密解密的鉴权信息,其中Base64是一种很简单的编码转换:
对于待编码数据,以3个字节为单位,依次取6位数据并在前面补上两个0形成新的8位编码,由于3×
8=4×
6,这样3个字节的输入会变成4个字节的输出,长度上增加了1/3。
上面的处理还不能保证得到的字符都是可见字符,为了达到此目的,Base64制定了一个编码表,进行统一的转换,见表2.1。
码表的大小为26=64,这也是Base64名称的由来。
由于编码是以3个字节为单位,当剩下的字符数量不足3个字节时,则应使用0进行填充,相应地,输出字符则使用‘=’占位,因此编码后输出的文本末尾可能会出现1至2个‘=’。
表2.1Base64编码表
值
编码
A
8
I
16
Q
24
Y
32
g
40
o
48
w
56
4
1
B
9
J
17
R
25
Z
33
h
41
p
49
x
57
5
2
C
10
K
18
S
26
a
34
i
42
q
50
y
58
6
3
D
11
L
19
T
27
b
35
j
43
r
51
z
59
7
E
12
M
20
U
28
c
36
k
44
s
52
60
F
13
N
21
V
29
d
37
l
45
t
53
61
G
14
O
22
W
30
e
38
m
46
u
54
62
+
H
15
P
23
X
31
f
39
n
47
v
55
63
/
BASE64的加密解析,SUN公司有自己内部专用的API,该API位于JRE/LIB下,但是该API并没有javadoc,属于不推荐使用的方法,将在后续JDK版本中被剔除,因为本设计根据Base64编码表,自行编写Base64加密解密方法。
分析电子邮件传输过程中的协议和加密算法后,本设计进行自主开发是可行的。
2.2产品功能需求分析
图2.2系统总体功能图
其中本设计实现的是一个电子邮件客户端,类似于Outlook,有用户邮箱账户设置,登陆验证,接收邮件,阅读邮件,保存邮件,发送邮件等功能。
发送邮件:
根据用户设置的公网邮箱账户或者一个公网不存在的自己私人域内的符合邮箱命名规范的邮箱账户,可实现对公网邮箱和本客户端(比如新浪,QQ,163)的邮件收发;
若邮箱账户是自己随机设置的账户,则不可以向除本客户端以外的邮件服务器发送邮件;
接收邮件:
接收来自本客户端私人邮箱发来的邮件,在接收邮件的同时,将对邮件进行默认保存,接收完成后,点击即可实现对邮件的阅读;
登陆验证:
客户端在启动的时候,会对用户的账户信息与客户端内部保存的信息,进行鉴权,防止旁人使用客户端乱发垃圾邮件;
账号设置:
这个功能主要是实现对邮件发送代理的选择,决定发送邮件功能的能力。
2.2电子邮件系统收发邮件的过程
图2.3收发邮件过程图
(1)发信人调用用户代理来编辑要发送的邮件。
用户代理用SMTP把邮件传送给发送端邮件服务器。
(2)发送端邮件服务器将邮件放入邮件缓存队列中,等待发送。
(3)运行在发送端邮件服务器的SMTP客户进程,发现在邮件缓存中有待发送的邮件,就向运行在接收端邮件服务器的SMTP服务器进程发起TCP连接的建立。
(4)TCP连接建立后,SMTP客户进程开始向远程的SMTP服务器进程发送邮件。
当所有的待发送邮件发完了,SMTP就关闭所建立的TCP连接。
(5)运行在接收端邮件服务器中的SMTP服务器进程收到邮件后,将邮件放入收信人的用户邮箱中,等待收信人在方便时进行读取。
收信人在打算收信时,调用用户代理,使用POP3(或IMAP)协议将自己的邮件从接收端邮件服务器的用户邮箱中的取回(如果邮箱中有来信的)。
第3章总体设计
图3.1系统的总体模型图
图3.1是该客户端的系统架构图,图中包含了六个图形用户界面,两个邮件接收和发送线程,以及一些相关的辅助方法和数据模型。
其中,各个图形用户界面是为了方便用户使用该客户端而设计;
用户鉴权和客户端配置信息,是主界面在加载时,针对每个特定的用户,加载其个人设置;
用户信息模型和账户信息模型用来对用户进行登录验证,设置邮箱账户时的信息进行封装。
发送邮件线程等待来自客户的发送请求,收到请求后,首先根据SMTP模型和用户输入信息,封装一个SMTP消息对象;
接着对用户账户和密码进行BASE64加密;
最后将封装好的信息对象,交由发送邮件方法进行发送;
邮件接收线程是客户端加载成功后,就开始监听25端口,当有邮件信息发送到来时,将接收到的信息封装到一个未读邮件模型中去,然后将该模型传递给邮件接收和保存方法,该方法将会对邮件在硬盘中进行保存,并更新客户端配置信息中得未读邮件信息。
3.2系统模块的划分
按照本系统的总体功能划分,可以将这个电子邮件客户端分成5大模块,首先是登录模块,作为验证需要;
其次是接收邮件模块,该模块负责邮件的接收,再次是发送模块,该模块负责该对方发送邮件;
接着是邮件处理模块,该模块负责邮件的阅读、保存等操作;
然后是邮件账户的管理,该操作负责设置客户端对公网的身份标识。
图3.2给出了本系统的模块体系:
图3.2系统模块体系图
第4章详细设计
4.1接收邮件模块
接收邮件模块主要由接收邮件线程监听端口完成对邮件的接收并对其进行保存和刷新主界面,包括下图中的几个部分。
(1)接收邮件线程。
一个邮件系统最基本的功能是能够接受发送的邮件。
为了可以同时接收多个邮件,保持并发性,本设计使用java多线程的功能,设计一个可以多线程的接收邮件线程;
(2)保存邮件。
接收到对方的邮件以后,必须先对邮件进行保存备份,然后将邮件信息封装到未读邮件模型后,再显示出来,可以隐去一些不必要的内容,只显示邮件关键信息给用户;
(3)刷新界面。
当客户端收到一个邮件后,必须能够实时刷新主界面以提醒用户。
接收邮件和附件模块的图示:
图4.1接收邮件和附件模块图
4.2发送和回复邮件模块
发送邮件模块主要由发送邮件线程文件完成,包括图中的几个部分。
(1)编写新邮件。
该部分也是电子邮件系统中最基本的功能。
(2)发送新邮件。
在编写完成新邮件后,电机该功能将邮件内容发送给对方。
发送邮件模块的图示:
图4.2发送邮件模块图
4.3邮件处理模块
邮件处理模块主要对邮件进行阅读和保存功能,包括图中的几个部分。
(1)显示邮件内容,新建一个界面显示用户选择的邮件内容。
在接收到邮件的同时,默认自动保存邮件。
(3)显示错误信息。
在出现一些登录错误,删除错误,发送错误时,将显示不同的错误信息提示用户。
邮件处理模块的图示:
图4.3邮件处理模块图
4.4界面实现的流程图
如上所述,本设计的邮件客户端需要六个不同的界面,都采用javaswing技术实现,javaswing提供丰富的图形组件和多样的布局方式,以及事件注册处理机制,在本设计中使用javaswing技术实现这些界面,其流程如图4.4所示:
图4.4界面实现流程图
其中的部分代码如下:
……
buttonPanel.add(newButton);
buttonPanel.add(recButton);
buttonPanel.add(recboxButton);
buttonPanel.add(draftButton);
buttonPanel.add(setButton);
……
jFrame.setBounds(0,0,SCREEN_WIDTH*3/4,SCREEN_HEIGHT*3/5);
jFrame.setBackground(Color.WHITE);
jFrame.add(buttonPanel,newBorderLayout().WEST);
jFrame.add(tab,newBorderLayout().CENTER);
jFrame.setVisible(true);
4.5邮件发送过程的流程图
邮件发送过程需要使用SMTP协议,因此在本设计中,将SMTP协议的各个字段封装到了一个对象中去,便于维护和管理,邮件发送的实现过程如图4.5所示,其部分实现代码如下
……
Stringdestip=getEmailNameInfo.getusername(username).replace("
_"
"
."
);
socket=newSocket(destip,PORT);
BufferedReaderbr=getReader(socket);
PrintWriterpw=getWriter(socket);
sendAndReceive(null,br,pw);
if(sendResult.equals(FAILED)){
JOptionPane.showMessageDialog(MainUI.jFrame,"
连接邮件服务器失败!
"
null,0);
return;
}
sendAndReceive(smtp.getMail(),br,pw);
if(sendResult.equals(FAILED)){return;
sendAndReceive(smtp.getRept(),br,pw);
sendAndReceive(smtp.getData(),br,pw);
sendAndReceive(message.getFrom()+"
\r\n"
+message.getTo()+"
+message.getData(),br,pw);
邮件发送失败!
sendAndReceive(smtp.getQuit(),br,pw);
邮件发送成功!
}
图4.5邮件发送过程
其中邮件发送过程分为如下几步:
1、发送HELO命令,并等到回复,若回复争取,则发送下一个命令,若失败停止发送,下面步骤皆是如此处理;
2、发送EHLO命令;
3、发送authlogin命令,进行用户名和密码的鉴权请求;
4、发送BASE64加密后的用户名;
5、发送BASE6加密后的密码;
6、若鉴权成功发送mailfrom命令;
7、发送rcptto命令,告知服务器邮件的接收方;
8、发送data命令,告知服务器接下来要发送邮件内容;
9、在本设计中邮件内容被封装到一个Message模型中,在本步中,发送的是该模型的一个对象;
10、在收到成功响应后,发送“.”结束发送过程。
4.6邮件接收流程
邮件接收流程是该设计的基本功能之一,其使用的仍是SMTP协议流程,在本设计中,针对收到的邮件会将其封装到一个未读邮件的对象中去,具体流程如图4.6所示,其部分代码如下所示:
图4.6邮件接收流程
while((request=br.readLine())!
=null){
if(request.contains("
mailfrom:
)&
&
request.contains("
@"
.com"
)
||request.contains("
.cn"
)){
isMAILFROM=true;
pw.println("
250senderok"
continue;
}elseif(!
isMAILFROM){
500commandnotrecognized"
rcptto:
isRCPTTO=true;
250recipientok"
isRCPTTO){
data"
isDATA=true;
354entercontent"
isDATA){
if(isDATA){
stringBuffer.append(request);
stringBuffer.append("
if(stringBuffer.toString().endsWith("
.."
isMessage=true;
content=stringBuffer.toString().substring(0,stringBuffer.toString().length()-1);
System.out.println("
contentis"
+content);
pw.println("
250ok"
}}
quit"
221"
+getEmailNameInfo.getHostname(e_mailConfig.getEmailCFG().getEmailname()));
privatePrintWritergetWriter(Socketsocket)throwsIOException{
//TODOAuto-generatedmethodstub
OutputStreamout=socket.getOutputStream();
returnnewPrintWriter(out,true);
}
privateBufferedReadergetReader(Socketsocket){
InputStreamis=null;
try{
is=socket.getInputStream();
}catch(IOExceptione){
e.printStackTrace();
BufferedReaderbr=newBufferedReader(newInputStreamReader(is));
returnbr;
}
4.7用户鉴权和客户端配置信息流程
该模块是在主界面加载前,针对不同的用户,加载相应的设置,其包含保存用户信息流程,更改用户信息流程,保存邮箱账户信息流程,更改邮箱账户信息流程,获取收到的邮件信息流程,设置邮件是否已读流程。
其中这三组流程处理方式一致,获取和更改用户信息流程如图4.7,4.8所示,部分处理代码如下。
4.7获取用户信息流程4.8更改用户信息流程图
protectedUsergetUserProfile(){
Useruser=newUser();
SAXBuilderbuilder=newSAXBuilder();
try
{Documentdoc=builder.build(USERFILE);
ElementrootElement=doc.getRootElement();
Stringusername=rootElement.getChild(USERNAME).getText();
user.setUsername(username);
Stringpassword=rootElement.getChild(PWD).getText();
user.setPassword(password);
booleanlogin=newBoolean(rootElement.getChild(LOGIN).getText());
user.setLogin(login);
catch(Exceptione