软件工程 实验报告.docx
《软件工程 实验报告.docx》由会员分享,可在线阅读,更多相关《软件工程 实验报告.docx(33页珍藏版)》请在冰豆网上搜索。
软件工程实验报告
中南民族大学
学生实验报告
院系:
计算机科学学院
专业:
计算机科学与技术
年级:
2013级
课程名称:
软件工程
组员:
司少武(1135)
兰少雄(1136)
张宇(1133)
纳洪泽(1132)
指导教师:
刘卫平
2015年12月26日
聊天室
1前言
即时消息系统的研究现状
即时消息系统[1](InstantMessenger,IM)是一种在后PC时代兴起的,以Internet网络为基础的,允许交互双方即时地传送文字、语音、视频等信息,能够跟踪网络用户在线状态的网络应用软件。
即时消息系统产生有着深刻的社会原因:
人们都有渴望社交,获得社会尊重、实现自我的需求,这正是即时消息软件风行的原动力,而物质文明的日益发达所带来副作用,又使得人们习惯与周围的人保持距离,以致人们更愿意对陌生人敞开心扉,在网络中可以跨越年龄、身份、行业、地域的限制,达到人与人、人与信息之间的零距离交流。
从这点上讲,即时消息系统的出现改变了人们的沟通方式和交友文化,大大拓展了个人生活交流的空间。
本工程的主要内容
随着互联网逐步普及,人们的生活和工作也越来越离不开信息网络的支持,而聊天室是人们最常见,最直接的网上交流的方式。
本聊天系统以聊天交流为主,为广大用户提供一个借助网络进行人际交往的平台,也是网络与现实最贴近的实用型网站。
本文所介绍的网络聊天系统是基于开放的JAVA应用程序开发设计的,其主要特性是能动态、实时的完成信息的传递,且具有高效的交互性,更有效的处理客户请求,且具有脱离数据库技术方法,易于维护和更新的特点。
2需求分析
本系统所要实现的主要功能是当用户聊天时,将当前用户名、聊天对象、聊天内容、聊天语气和是否私聊进行封装,然后与服务器建立Socket连接,再用对象输出流包装Socket的输出流将聊天信息对象发送给服务器端
当用户发送聊天信息时,服务端将会收到客户端用Socket传输过来的聊天信息对象,然后将其强制转换为Chat对象,并将本次用户的聊天信息对象添加到聊天对象集Message中,以供所有聊天用户访问。
接收用户的聊天信息是由多线程技术实现的,因为客户端必须时时关注更新服务器上是否有最新消息,在本程序中设定的是3秒刷新服务器一次,如果间隔时间太短将会增加客户端与服务器端的通信负担,而间隔时间长就会让人感觉没有时效性,所以经过权衡后认为3秒最佳,因为每个用户都不可能在3秒内连续发送信息。
当每次用户接收到聊天信息后将会开始分析聊天信息然后将适合自己的信息人性化地显示在聊天信息界面上。
业务需求
1.与聊天室成员一起聊天。
2.可以与聊天室成员私聊。
3.可以改变聊天内容风格。
4.用户注册(含头像)、登录。
5.服务器监控聊天内容。
6.服务器过滤非法内容。
7.服务器发送通知。
8.服务器踢人。
9.保存服务器日志。
10.保存用户聊天信息。
系统功能模块
服务器端
1.处理用户注册
2.处理用户登录
3.处理用户发送信息
4.处理用户得到信息
5.处理用户退出
客户端
1.用户注册界面及结果
2.用户登录界面及结果
3.用户发送信息界面及结果
4.用户得到信息界面及结果
5.用户退出界面及结果
性能需求
运行环境:
WindowsAll
必要环境:
JDK以上
硬件环境:
CPU400MHz以上,内存64MB以上
3数据结构
数据结构
此系统数据库中储存信息采用字符指针储存,将用户的信息用字符的形式进行处理并储存。
逻辑结构
逻辑结构:
用户向服务器发送请求,服务器获取对方IP,若获取成功,用户向其发送消息,服务器将其处理并将其记录,然后将消息发给另一用户。
其E—R图如下所示:
2
消息
发送
服务器
记录
记录信息
内容
时间
内容
储存信息
图图
服务器IP
将E-R图转化为关系模型,建立关系模型为:
消息(内容,时间);
记录信息(内容,储存信息);
服务器(服务器IP);
3
功能模块划分
结构框图
聊天系统
发送消息
接受消息
服务器获取IP
服务器发送消息
保存信息
时钟
图2.结构图
程序流图
(1)整个系统流程图如下:
用户发送的消息或请求
结束
服务器接收信息
查询请求
向用请求户发送消息
保存信息
向目标用户发送消息
是
否
图3.系统程序流程图
模块功能分析及外部设计
模块功能分析:
(1)发送消息:
用户选择好友,如果好友在线,服务器便获取其IP地址,用户打开消息盒编辑需要发送的消息,然后发送,服务器接受此消息,并处理记录到记录表中,然后将其发送给好友。
(2)接收消息:
好友发送的信息通过服务器处理并发送到本用户,如果设置为接收消息,则系统提示并可以打开查看此消息,否则服务器不将此消息发送到本用户。
(3)消息记录查询:
用户向服务器发送查询请求,服务器作出响应并将最近消息记录发送到此用户。
外部设计:
交互设计是面向最终用户的设计,是软件的外部设计,交互设计要求在研究软件技术问题的同时对人加以研究。
用户是什么样的人用户怎样与新的计算机系统进行交互用户怎样解释系统产生的信息用户对系统有哪些期望这些问题仅仅是需要在用户交互设计时必须询问和回答的问题。
作为点对点的聊天系统,作为服务使用者得用户和提供服务的聊天系统有着互动和交换信息的过程,用户有请求,系统就必须有应答,需要双方参与。
(1)当用户选择好友向其发送消息时,点击好友,向服务器发送请求,如果好友在线,服务器自动获取好友IP并建立双方的连接,进行聊天。
否则应该提示好友不在,不能聊天或发送离线信息。
(2)用户查询聊天信息时,向服务器发送查询请求,服务器作出响应并将相应记录发送到此用户界面。
通过对产品的界面和行为进行交互设计,让产品和它的使用者之间建立一种有机关系,从而可以有效的达到使用者的目标,而好的交互设计会使系统和使用者之间更好的交互,达到“愉悦地合作”,这是交互设计的最终目的。
4详细设计
类定义
为客户端程序启动类,负责客户端的启动和退出。
为客户端程序登录界面,负责用户帐号信息的验证与反馈。
为客户端程序注册界面,负责用户帐号信息的注册验证与反馈。
为客户端程序聊天室主界面,负责接收、发送聊天内容与服务器端的亲密合作。
Windowclose为的内部类,负责监听聊天室界面的操作,当用户退出时返回给服务器信息。
为客户端程序的一个小程序,实现的一个石英钟功能。
主要模块内部设计
此点对点聊天系统主要包括以下模块:
(1)发送消息;
(2)接收消息;(3)查询消息记录。
每个模块的主要执行功能函数及算法如下。
模块1设计
模块算法
模块一:
发送消息:
发送消息函数:
sendmessages(char*p,InetAdrress);
发送消息后自动执行储存函数:
memorymessages(InetAdrress,char*p);
流程图
用户输入要发送的信息
是否在线
获取IP
发送消息
保存记录
结束
是
否
图4.发送消息流程图
4.2.2模块2设计
模块算法
模块二:
接收消息:
接收消息消息函数:
*receivemessages(InetAdrress,char*p);
接收消息后自动执行储存消息函数:
memorymessages(InetAdrress,char*p);
流程图:
好友发送的消息
是否接收
打开消息
保存消息记
结束
图5.接收消息流程图
是
否
4.2.3模块3设计
模块算法
模块三:
消息记录查询:
执行发送请求函数:
*checknotes(InetAdrress,char*p);
删除记录函数:
deletenotes(InetAdrress);
自动执行接收消息函数:
*receivemessages(InetAdrress,char*p);
流程图:
用户发送的查询请求
是否存在记录
服务器向其发送记录
读取记录
结束
是
否
图6.查询记录流程图
5测试分析与截图
在实现本系统的同时每设计一个模块,就实现模块测试,使其能实现该函数需要实现的功能,此阶段为白盒测试。
此阶段将此模块作为单独的一个实体来测试,而且比较容易实际检验模块正确性的测试方案,保证每个模块单元的正确运行,来确定编码和详细设计的错误。
然后集成测试。
集成测试阶段,先将单元测试成功的模块放在一起形成一个子系统来测试,以解决模块间的协调和通信问题。
然后将子系统测试通过的模块放在一起形成一个完整的系统测试,检验功能,来发现需求报告中的错误。
测试用例
为了检验此系统的正确性,设计了以下的一些测试用例:
(1)登录注册
(2)发送和接收消息
A:
你好
B:
你好
(3)保存聊天记录
(4)保存聊天记录
(5)保存服务器日志
(6)服务器踢人
不同的测试数据发现程序错误的能力差别很大,为了提高测试效率低测试成本,应该选择高效的测试用例,数据尽量少,做到尽可能完备的测试就可以了。
测试结果
登录界面
注册界面
服务器
聊天室聊天
对所有人,私人聊天,系统提示信息。
聊天记录保存
服务器日志保存
服务器踢人
时钟
6结束语
Java面向对象程序设计是一门应用广泛并且实用性极强的高级程序设计语言。
通过本次课程设计,我们对面向对象的基本思想有了进一步的理解,对项目的各个阶段的任务也有了一定的了解。
设计开始阶段必须明确设计的目的与需求分析,总体设计要全面分析聊天室系统的架构。
通过这次设计,使我们认识到体系的架构是最重要的,只有准确的系统设计、很好的定义各个模块及模块之间的关系,才能在编码阶段更轻松的的实现。
通过这次课程设计,对我们的逻辑思维能力是一个很大的锻炼,它不仅加强了我们的系统思考问题的能力,而且还改变了我们以前不好的编程习惯,虽然花费了不少的时间,但是我们学到了丰富的知识。
另外,此次课程设计也提高了我们的团对合作精神,让我们明白不是不能一个人能单独完成,而是要集思广益,结合更多的人的创意思维。
让我们大家深刻的体会到理论与实际相结合的重要性与微妙之处。
对于不同的想法我们都会集中讨论并对好的意见加以借鉴,在这个讨论的过程中,还更正了不少我们各自自身对于某个知识点的误区。
这次程序设计也是一个毅力的考验过程。
有时候往往只是一个小小的错误,却要花出几小时甚至是一两天的时间才可能发现它。
所以在这个过程不能过于急躁,要很有耐心将程序反复调试。
App
import.*;
import.*;
import.*;
publicclassAppServerextendsThread{
privateServerSocketserverSocket;
privateServerFramesFrame;
privatestaticVectoruserOnline=newVector(1,1);
privatestaticVectorv=newVector(1,1);
publicAppServer(){
sFrame=newServerFrame();
try{
serverSocket=newServerSocket(1001);
.");
();dd(pnlLogin);
lblServer=newJLabel("服务器(S):
");
lblUserName=newJLabel("用户名(U):
");
lblPassword=newJLabel("口令(P):
");
txtServer=newJTextField(20);
("");
txtUserName=newJTextField(20);
pwdPassword=newJPasswordField(20);
btnLogin=newJButton("登录(L)");
("登录到服务器");
('L');
btnRegister=newJButton("注册(R)");
("注册新用户");
('R');
btnExit=newJButton("退出(X)");
("退出系统");
('X');
(null);
(newColor(52,130,203));
(50,100,100,30);
(150,100,120,25);
(50,130,100,30);
(150,130,120,25);
(50,160,100,30);
(150,160,120,25);
(50,200,80,25);
(130,200,80,25);
(210,200,80,25);
Fontfontstr=newFont("宋体",,12);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
;
;
;
;
;
(lblServer);
(txtServer);
(lblUserName);
(txtUserName);
(lblPassword);
(pwdPassword);
(btnLogin);
(btnRegister);
(btnExit);
Iconlogo1=newImageIcon("images\\");
lblLogo=newJLabel(logo1);
(0,0,340,66);
(lblLogo);
setResizable(false);
setSize(340,260);
setVisible(true);
scrnsize=();
setLocation/2-()/2,
/2-()/2);
Imageimg=("images\\");
setIconImage(img);
(this);
(this);
(this);
@SuppressWarnings({"deprecation","static-access"})
publicvoidactionPerformed(ActionEventae){
Objectsource=();
if(btnLogin)){
if().equals("")
||().equals("")){
JOptionPaneop1=newJOptionPane();
(null,"用户名或密码不能为空");
}else{
strServerIp=();
login();
}
}
if(btnRegister)){
strServerIp=();
();
newRegister(strServerIp);
}
if(source==btnExit){
(0);
}
}
@SuppressWarnings("deprecation")
publicvoidlogin(){
Customerdata=newCustomer();
=();
=();
try{
SockettoServer;
toServer=newSocket(strServerIp,1001);
ObjectOutputStreamstreamToServer=newObjectOutputStream(toServer
.getOutputStream());
((Customer)data);
BufferedReaderfromServer=newBufferedReader(
newInputStreamReader()));
Stringstatus=();
if("登录成功")){
newChatRoom((String),strServerIp);
();
();
();
();
}else{
(null,status);
();
();
();
}
}catch(ConnectExceptione1){
(null,"未能建立到指定服务器的连接!
");
}catch(InvalidClassExceptione2){
(null,"类错误!
");
}catch(NotSerializableExceptione3){
(null,"对象未序列化!
");
}catch(IOExceptione4){
(null,"不能写入到指定服务器!
");
}
}
publicstaticvoidmain(Stringargs[]){
newLogin();
}
}
import*;
publicclassRegisterextendsJFrameimplementsActionListener
{
privateJComboBoxcomboBox;
privatestaticfinallongserialVersionUID=902180L;
JPanelpnlRegister;
JLabellblUserName,lblGender,lblAge;
JLabellblPassword,lblConfirmPass,lblEmail,logoPosition;
JTextFieldtxtUserName,txtAge,txtEmail;
JPasswordFieldpwdUserPassword,pwdConfirmPass;
JRadioButtonrbtnMale,rbtnFemale;
ButtonGroupbtngGender;
JButtonbtnOk,btnCancel,btnClear;
StringstrServerIp;
finalJLabelheadLabel=newJLabel();
Dimensionscrnsize;
Toolkittoolkit=();
publicRegister(Stringip)
{
super("[HappyChat]聊天室注册窗口");
strServerIp=ip;
pnlRegister=newJPanel();
().add(pnlRegister);
lblUserName=newJLabel("用户名:
");
lblGender=newJLabel("性别:
");
lblAge=newJLabel("年龄:
");
lblPassword=newJLabel("口令:
");
lblConfirmPass=newJLabel("确认口令:
");
lblEmail=newJLabel("电子邮件:
");
txtUserName=newJTextField(30);
txtEmail=newJTextField(30);
txtAge=newJTextField(10);
pwdUserPassword=newJPasswordField(30);
pwdConfirmPass=newJPasswordField(30);
rbtnMale=newJRadioButton("男",true);
rbtnFemale=newJRadioButton("女");
btngGender=newButtonGroup();
btnOk=newJButton("确定(O)");
('O');
("保存注册信息");
btnCancel=newJButton("返回(B)");
('B');
("返回登录窗口");
btnClear=newJButton("清空(L)");
('L');
("清空注册信息");
(null);
(newColor(52,130,203));
(30,80,100,30);
(110,85,120,20);
(30,141,100,30);
(110,146,120,20);
(30,166,100,30);
(110,171,120,20);
(30,191,100,30);
(110,196,60,20);
(190,196,60,20);
(30,216,100,30);
(110,221,120,20);
(30,241,100,30);
(110,246,120,20);
(246,166,80,25);
(246,201,80,25);
(246,241,80,25);
Fontfontstr=newFont("宋体",,12);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
(fontstr);
;
;
;
;
lblConfirmPass.setForeground;
;
;
;
;
;
;
;
;
(false);
(false);
(lblUserName);
(lblGender);
(lblPassword);
(lblConfirmPass);
(lblEmail);
(lblAge);
(txtAge);
(txtUserName);
(txtEmail);
(pwdUserPasswo