计算机网络课程设计—通讯录软件系统设计.docx
《计算机网络课程设计—通讯录软件系统设计.docx》由会员分享,可在线阅读,更多相关《计算机网络课程设计—通讯录软件系统设计.docx(50页珍藏版)》请在冰点文库上搜索。
《计算机网络》
课程设计报告
题目:
通讯录软件系统
学生姓名:
指导老师:
学院:
信息科学与工程学院
专业班级:
物联网工程1402班
完成时间:
2016年10月16日
目录
第一章需求分析 3
1.1服务器端功能要求 3
1.2客户端功能要求 3
第二章总体设计 3
2.1总体结构 3
2.2模块关系 3
2.3流程图 4
第三章详细设计 5
3.1客户端 5
3.2服务器端 8
3.3函数调用关系 11
第四章调试分析 12
第五章运行结果 13
5.1登录功能 13
5.2查询本机通讯录 14
5.3备份每个用户的通讯录 15
5.4更新每个用户的通讯录 16
5.5加密功能 18
第六章课程设计总结 18
参考文献 20
附录 20
第一章需求分析
本设计要求完成一个基于C/S模式的通讯录备份软件。
采用C/S架构。
应该具有易用、美观的图形界面。
1.1服务器端功能要求
(1)能够验证客户身份,接收客户端的备份通讯录的请求,能够实时备份和更新客户的通讯录。
(2)加密存储每个用户的通讯录
1.2客户端功能要求
(1)能登陆连接到服务器,回应:
连接成功/失败。
(2)能备份本机通讯录。
(3)能实时更新本机通讯录。
(4)能查询本机通讯录。
第二章总体设计
2.1总体结构
客户端建立一个本地文件存储本地数据,通过对文件进行读写操作,实现本地数据的增、删、查等功能。
登录成功后,可以将本地联系人信息备份到服务器,当本地文件中的联系人信息意外丢失时,可以将服务器端的备份内容更新到本地联系人信息,类似于微信的联系人备份和导出功能。
服务器负责验证客户端的登录账号和密码,并通过JDBC与Mysql建立连接。
在客户登录成功后,响应客户端的备份请求,实现联系人数据的加密存储;响应客户端的更新要求,将客户联系人信息导入到本地文件中。
2.2模块关系
本地增删查改
图2.2通讯录系统模块关系图
2.3流程图
图2.3通讯录系统流程图
第三章详细设计
如图3.1所示,一共建立了两个包,客户端和服务器。
图3.1通讯录软件工程包展开图
3.1客户端
客户端的三个类分别为Login,LoginListener,Operation。
3.1.1Login类
实现登录界面,如图3.2所示,并实例化LoginListener类给登录按钮添加ActionListner监听方法。
图3.2通讯录系统客户端登录界面
3.1.2LoginListener类
实现ActionListener类,重写抽象函数ActionPerformed。
当单击登录按钮时,利用Socket连接到服务器,将客户的账号和密码传给服务器,等待服务器传来的验证结果。
验证通过则弹出操作主界面,失败则弹出用户名或密码错误的窗体。
响应单击登录按钮的代码如下所示。
publicvoidactionPerformed(ActionEvente){
try{
//发送密码和用户名到客户端
Stringuser=text.getText();
Stringpass=pw.getText();
Sockets=newSocket("127.0.0.1",8000);
OutputStreamos=s.getOutputStream();
OutputStreamWriterosw=newOutputStreamWriter(os);
PrintWriterpw=newPrintWriter(osw,true);
pw.println(user+"%"+pass);
//接收服务器发回来的确认信息
InputStreamis=s.getInputStream();
InputStreamReaderisr=newInputStreamReader(is);
BufferedReaderbr=newBufferedReader(isr);
Stringyorn=br.readLine();
//显示登录成功界面或密码错误界面
if(yorn.equals("ok")){
Operationo=newOperation();
o.SetSocket(s);
frame.dispose();
}
else{
JTextFieldtext=newJTextField("用户名或密码错误");
JFrameframe=newJFrame();
frame.setTitle("错误");
frame.setLocation(550,300);
frame.setSize(200,100);
frame.setDefaultCloseOperation
(2);
frame.add(text);
frame.setVisible(true);
}
}catch(Exceptione1){}
}
3.1.3Operation类
实现操作主界面,如图3.3所示,同样implementsActionListener类,重写抽象方法ActionPerfomed。
实现监听的代码风格不同于登录按钮,没有重新创建一个类,直接在构造方法中实现。
图3.3通讯录系统客户端主界面
Operation中重要的一点是实现Socket的传递,在单击登录后,客户端会实Socket对象而不能重新实例化一个新的对象,实现值传递的方法如下。
在Operation中定义一个方法SetSocket,在LoginListener中收到服务器传来验证成功的指令后,实例化Operation对象,并调用SetSocket函数实现Socket的传递。
SetSocket方法及其调用如下所示。
publicSockets;
publicvoidSetSocket(Sockets){
this.s=s;
}
if(yorn.equals("ok")){
Operationo=newOperation();
o.SetSocket(s);
frame.dispose();
}
3.2服务器端
服务器端的三个类分别实现为ServerFrame、Sever、DESPlus。
3.2.1SeverFrame类
简单实现了一个服务器端的窗体,用来显示客户端是否登录成功和客户端发来的指令。
如图3.4所示。
图3.4通讯录备份软件服务器端显示窗体
3.2.2Server类
是服务器端的主体部分,实现的功能有响应客户端的登录请求,连接Mysql,响应客户端的备份、更新请求。
响应登录代码:
//服务器在8000端口监听
@SuppressWarnings("resource")
ServerSocketss=newServerSocket(8000);
System.out.println("服务器正在8000端口监听……");
Sockets=ss.accept();
//接收用户名和密码
InputStreamis=s.getInputStream();
InputStreamReaderisr=newInputStreamReader(is);
BufferedReaderbr=newBufferedReader(isr);
Stringuandp=br.readLine();
Stringu=uandp.split("%")[0];
Stringp=uandp.split("%")[1];
//将用户名密码的验证结果传送到客户端
OutputStreamos=s.getOutputStream();
OutputStreamWriterosw=newOutputStreamWriter(os);
PrintWriterpw=newPrintWriter(osw,true);
if(u.equals("siru")&&p.equals("123")){
pw.println("ok");
sf.text.append("客户登录成功"+"\n");
}else{
//发送错误信号到客户端
pw.println("error");
}
响应客户端备份和更新指令的代码:
//响应客户端备份命令
if(message.equals("备份")){
sf.text.append("备份联系人信息"+"\n");
Class.forName("org.gjt.mm.mysql.Driver");
Connectioncn=DriverManager.getConnection("jdbc:
mysql:
//127.0.0.1:
3306/通讯录","root","");
Statementst=cn.createStatement();
st.executeUpdate("deletefrom联系人wherenameisnotnull");
Stringstring=br.readLine();
while(!
string.equals("end")){
Stringname=string.split("")[0];
Stringtelephone=string.split("")[1];
PreparedStatementps=cn.prepareStatement("insertinto联系人(name,telephone)values(?
?
)");
ps.setString(1,desPlus.encrypt(name));
ps.setString(2,desPlus.encrypt(telephone));
ps.executeUpdate();
string=br.readLine();
}
pw.println("备份成功");
}
//响应客户端更新的命令
if(message.equals("更新")){
sf.text.append("更新联系人信息"+"\n");
Class.forName("org.gjt.mm.mysql.Driver");
Connectioncn=DriverManager.getConnection("jdbc:
mysql:
//127.0.0.1:
3306/通讯录","root","");
Statementst=cn.createStatement();
ResultSetrs=st.executeQuery("selectname,telephonefrom联系人");
while(rs.next()){
Stringstring=newString();
string=rs.getString
(1)+""+rs.getString
(2);
pw.println(string);
}
pw.println("更新成功");
3.2.3DESPlus类
实现联系人信息的的加密,使用DES对称加密算法。
开始的时候采用的是RSA算法,但是很简单的信息加密后的内容却很长,需要很大的储存空间所以就放弃RSA,选择了DES,计算量较小,速度也更快。
服务器在响应备份指令时将客户端传来的信息加密后存入数据库,在响应更新指令时将数据库的信息解密后传到客户端。
3.3函数调用关系
3.3.1服务器端
主函数在Server中,运行Server,先调用ServerFrame类的构造函数实例化一个对象,接下来等待客户端的请求,接收请求后执行Main函数中对应的代码段。
3.3.2客户端
主函数在Operation类中,运行客户端程序,首先调用Login类的构造函数实例化Login对象,显示登录界面;若用户名和密码正确,响应登录按钮的监听,调用Operation类的构造方法实例化Operation对象,显示操作主界面。
第四章调试分析
这次的课程设计和以往的有很大不同,因为是一个较大的项目,所以我是在每完成一个阶段后进行一次调试。
比如说,首先写的是客户端的Login类,在写好这个类之后,就在类中写了一个主函数,简单的测试一下是否可以运行出想要的登录界面。
确定没有问题之后,再给登录按钮添加监听,接着去检测监听的添加是否正常,这样一步一调试的方式可以及时发现逻辑错误和异常(语法错误在写的过程中通过编译提示随时解决)。
当然在测试的过程中碰到了很多异常,很多不明的错误,这种情况下我会在怀疑有错误的代码段写几条输出语句,设置检验点来判断是否该代码段出错。
这个项目遇到最多的异常是空指针异常,因为涉及到多个类,就会有值传递的问题,同样一行代码写的位置不合适就会导致异常。
但是采用上面提到的方法,一点一点进行调试,最终还是得到了满意的结果。
例如,在为登录界面的登录按钮设置监听时,创建了一个监听类,LoginListen类,在这个类中判断用户输入的账号和密码是否正确,则需获取Login类中的frame,text,pw属性,所以在LoginListener类中创建如下所示的函数,在Login中实例化LoginListener后,调用该方法,就可以将所需变量传给LoginListener类。
/**
*获取Login类中的frametextpw属性
*@paramframe
*@paramtext
*@parampw
*/
publicLoginListener(JFrameframe,JTextFieldtext,JPasswordFieldpw){
this.frame=frame;
this.text=text;
this.pw=pw;
}
当然,这个程序还有许多可以改进的地方,比如用户界面不够美观漂亮,功能方面,注册功能还不够完善。
第五章运行结果
5.1登录功能
程序启动后,首先出现登录界面如图5.1所示
图5.1通讯录备份软件客户端登录窗口
若用户名和密码错误,则登录失败,弹出体现窗口,如图5.2所示
图5.2通讯录备份系统登录错误提示界面
若用户名和密码正确,则登录成功,出现操作主界面,如图5.3所示
图5.3通讯录系统操作主界面
5.2查询本机通讯录
查询功能有两种,可以查询所有的本地联系人信息,也可以查询确定某个联系人的信息。
切换到查询界面后,如果想要查询所有联系人信息,直接单击确认按钮,就可以看到得到的结果如图5.4所示
图5.4通讯录系统查询所有联系人
如果想要查询某个确定联系人信息,则在下方输入框内输入联系人姓名,就可以查询到具体的信息,如图5.5所示
图5.5通讯录系统查询条件查询联系人信息、
如果没有所查联系人信息,系统会提示错误,如图5.6所示
图5.6通讯录系统查询联系人不存在
5.3备份每个用户的通讯录
在客户端有一个本地文件存储本地联系人信息,服务器端连接数据库mysql接收备份的请求,将客户的联系人信息备份存储到对应的数据库中。
单击备份按钮,就可以实现备份功能,界面提示操作成功如图5.7所示
图5.7通讯录系统备份界面
再到数据库中检测一下是否真正存在备份成功的联系人信息
没有备份之前的数据库,如图5.8所示
图5.8通讯录系统备份前的数据库
备份成功后的数据库,如图5.9所示(为了可以看清楚备份的内容,本次运行时暂时将加密语句进行了注释)
图5.9通讯录系统备份成功后的数据库
5.4更新每个用户的通讯录
当存储本地联系人信息的文件意外丢失时,可以通过备份按钮实时从服务器获取当前用户的联系人信息,并存储到本地文件中,如图5.10所示
图5.10通讯录系统更新联系人信息
再到本地文件中检查一下是否有更新成功的联系人信息,更新之前现将本地文件中的联系人全部删除,如图5.11所示:
图5.11通讯录系统更新前本地存储联系人信息的空文档
更新成功后的本地联系人文档,如图5.12所示:
图5.12通讯录系统更新成功后的本地存储联系人信息的文档
5.5加密功能
在客户发出备份请求时,服务器会将客户的信息用DES算法加密后在存入数据库中,而在客户发出更新请求时,服务器会将数据库中的信息解密后在传到客户端。
实现了数据库加密存储。
数据库中的数据如图5.13所示。
图5.13通讯录系统服务器端数据库加密存储数据
第六章课程设计总结
刚拿到这个题目的时候,感觉有点无从下手。
这次的课设是一个小项目,涉及到客户端、服务器、之间的连接、还需要添加数据库。
这里包括一些我不太熟悉的内容,只能一点点从头学起。
从客户端开始着手,因为对图形界面还比较熟悉,我首先做出来的是登录界面和通讯录系统的主界面,因为还没有连接数据库,只能简单的通过登录按钮的监听将两个界面联系起来。
接下来开始写服务器端,同样的是先做出一个简单的界面方便管理人员查看客户端进行的操作,然后利用Socket套接字将服务器和客户端连接到一起。
这时大体的框架就基本完成了,还需要重要的一步就是连接数据库,这部分内容完全是要自学完成。
去图书馆找了相关的入门级的书,跟着敲了一天的代码,掌握的基本内容足够完成这次课设的内容了。
到此,大体的代码已经就写好了,接下来做一些细节的修改,使系统更方便操作。
在完成课设的过程中,遇到了很多问题。
调试代码的时候,程序运行过程中会抛出很多莫名的异常。
因为程序较长不太好测试,我会选择新建一个test类,写入抛出异常的代码段,在程序的关键点写一条输出语句,通过在控制端的输出和抛出异常的类型来判断代码的具体错误。
其中最麻烦调试时间最长的是对文件的一个操作,没有逻辑错误,没有异常抛出,但是得到的内容总是不全,看了书上java关于文件的操作内容、查了java的文档,还是没有找到问题的所在,最后去找了java相关的老师,才知道是我函数使用的问题。
下面是错误代码,错误就在于if判断语句中,通过br.readline()进行一次判断后,没有及时保存用于判断的这条信息,这条信息就直接丢失了,因此,读到的内容全部都是偶数行的。
当你找到问题的所在后,可能觉得这是一个极其简单的错误,但是发现问题的过程却能学到很多相关的知识(尤其是通过自查阅资料的方式),一次次的发现问题解决问题,收获很多。
错误代码:
//指定文件目录并建立输出字符流
Filef=newFile("D:
\\Programming\\Java\\通讯录备份软件\\Data.txt");
FileWriterfw=newFileWriter(f);
PrintWriterpw1=newPrintWriter(fw);
//读取文件数据,传送并在控制台打印
while(br.ready()){
if(null!
=br.readLine()){
pw1.append(br.readLine()+"\r\n");
System.out.println(br.readline());
}
}
除此之外,在搭建数据库的时候也遇到了一些困难,之前在做数据库课程的实验时,使用的是SqlServer,是微软公司开发的一个软件,不能免费使用。
而Mysql是一个免费并且更简洁的数据库,这次便选择了使用Mysql。
第一次安装没有安装成功,接下来又试了几次,都没办法安装成功。
于是我在网上查了一些资料,Mysql安装没有成功有时也会生成一些注册表,而删除的时候这些注册表如果没有删除干净,也会导致下一次安装。
知道了原因之后,找到注册表删除之后,再次安装,终于成功了。
我觉得通过这次课程设计,收获的有很多以前不知道的知识,提高了编程能力,动手能力,还有很重要的一点是提高了自己解决问题的能力,在自己解决的过程中,总会有意外的收获。
参考文献
[1]《Java就该这样学》王洋电子工业出版社
[2]《Java实用教程》郑阿奇电子工业出版社
[3]《Java语言程序设计》郭克华、段桂华清华大学出版社
附录
Login类:
packageClient;
importjava.awt.BorderLayout;
importjava.awt.Color;
importjava.awt.Dimension;
importjava.awt.FlowLayout;
importjavax.swing.ImageIcon;
importjavax.swing.JButton;
importjavax.swing.JCheckBox;
importjavax.swing.JFrame;
importjavax.swing.JLabel;
importjavax.swing.JPanel;
importjavax.swing.JPasswordField;
importjavax.swing.JTextField;
importClient.LoginListener;
publicclassLogin{
publicLogin(){
//实例化一个窗体;
JFrameframe=newJFrame();
frame.setTitle("通讯录系统登录");
frame.setLocation(300,150);
frame.setSize(480,380);
frame.setDefaultCloseOperation(3);
//实例化northpanel并添加到窗体上
JPanelnorthpanel=newJPanel();
northpanel.setBackground(newColor