当前位置:文档之家› 软件工程 实验报告

软件工程 实验报告

院系:计算机科学学院专业:计算机科学与技术年级: 2013级课程名称:软件工程组员:司少武(1135)兰少雄(1136)张宇(1133)纳洪泽(1132)指导教师:刘卫平2015年 12月 26 日聊天室1 前言即时消息系统的研究现状即时消息系统[1](Instant Messenger,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.用户退出界面及结果性能需求运行环境:Windows All必要环境:JDK 以上硬件环境:CPU 400MHz以上,内存64MB以上3数据结构数据结构此系统数据库中储存信息采用字符指针储存,将用户的信息用字符的形式进行处理并储存。

逻辑结构逻辑结构:用户向服务器发送请求,服务器获取对方IP,若获取成功,用户向其发送消息,服务器将其处理并将其记录,然后将消息发给另一用户。

其E—R图如下所示:2将E-R图转化为关系模型,建立关系模型为:消息(内容,时间);记录信息(内容,储存信息);服务器(服务器IP);3功能模块划分结构框图程序流图(1)整个系统流程图如下:模块功能分析及外部设计模块功能分析:(1)发送消息:用户选择好友,如果好友在线,服务器便获取其IP地址,用户打开消息盒编辑需要发送的消息,然后发送,服务器接受此消息,并处理记录到记录表中,然后将其发送给好友。

(2)接收消息:好友发送的信息通过服务器处理并发送到本用户,如果设置为接收消息,则系统提示并可以打开查看此消息,否则服务器不将此消息发送到本用户。

(3)消息记录查询:用户向服务器发送查询请求,服务器作出响应并将最近消息记录发送到此用户。

外部设计:交互设计是面向最终用户的设计,是软件的外部设计,交互设计要求在研究软件技术问题的同时对人加以研究。

用户是什么样的人?用户怎样与新的计算机系统进行交互?用户怎样解释系统产生的信息?用户对系统有哪些期望?这些问题仅仅是需要在用户交互设计时必须询问和回答的问题。

作为点对点的聊天系统,作为服务使用者得用户和提供服务的聊天系统有着互动和交换信息的过程,用户有请求,系统就必须有应答,需要双方参与。

(1)当用户选择好友向其发送消息时,点击好友,向服务器发送请求,如果好友在线,服务器自动获取好友IP并建立双方的连接,进行聊天。

否则应该提示好友不在,不能聊天或发送离线信息。

(2)用户查询聊天信息时,向服务器发送查询请求,服务器作出响应并将相应记录发送到此用户界面。

通过对产品的界面和行为进行交互设计,让产品和它的使用者之间建立一种有机关系,从而可以有效的达到使用者的目标,而好的交互设计会使系统和使用者之间更好的交互,达到“愉悦地合作”,这是交互设计的最终目的。

4 详细设计类定义为客户端程序启动类,负责客户端的启动和退出。

为客户端程序登录界面,负责用户帐号信息的验证与反馈。

为客户端程序注册界面,负责用户帐号信息的注册验证与反馈。

为客户端程序聊天室主界面,负责接收、发送聊天内容与服务器端的亲密合作。

Windowclose 为的内部类,负责监听聊天室界面的操作,当用户退出时返回给服务器信息。

为客户端程序的一个小程序,实现的一个石英钟功能。

主要模块内部设计此点对点聊天系统主要包括以下模块:(1)发送消息;(2)接收消息;(3)查询消息记录。

每个模块的主要执行功能函数及算法如下。

模块1设计模块算法模块一:发送消息:发送消息函数:send messages(char *p,InetAdrress);发送消息后自动执行储存函数:memory messages(InetAdrress,char *p);流程图4.2.2模块2设计模块算法模块二:接收消息:接收消息消息函数: *receive messages(InetAdrress,char *p);接收消息后自动执行储存消息函数:memory messages(InetAdrress,char *p);流程图:4.2.3模块3设计模块算法模块三:消息记录查询:执行发送请求函数:*check notes(InetAdrress,char *p);删除记录函数:delete notes(InetAdrress);自动执行接收消息函数:*receive messages(InetAdrress,char *p);流程图:5 测试分析与截图在实现本系统的同时每设计一个模块,就实现模块测试,使其能实现该函数需要实现的功能,此阶段为白盒测试。

此阶段将此模块作为单独的一个实体来测试,而且比较容易实际检验模块正确性的测试方案,保证每个模块单元的正确运行,来确定编码和详细设计的错误。

然后集成测试。

集成测试阶段,先将单元测试成功的模块放在一起形成一个子系统来测试,以解决模块间的协调和通信问题。

然后将子系统测试通过的模块放在一起形成一个完整的系统测试,检验功能,来发现需求报告中的错误。

测试用例为了检验此系统的正确性,设计了以下的一些测试用例:(1)登录注册(2)发送和接收消息A:你好B:你好(3)保存聊天记录(4)保存聊天记录(5)保存服务器日志(6)服务器踢人不同的测试数据发现程序错误的能力差别很大,为了提高测试效率低测试成本,应该选择高效的测试用例,数据尽量少,做到尽可能完备的测试就可以了。

测试结果登录界面注册界面服务器聊天室聊天对所有人,私人聊天,系统提示信息。

聊天记录保存服务器日志保存服务器踢人时钟6 结束语Java面向对象程序设计是一门应用广泛并且实用性极强的高级程序设计语言。

通过本次课程设计,我们对面向对象的基本思想有了进一步的理解,对项目的各个阶段的任务也有了一定的了解。

设计开始阶段必须明确设计的目的与需求分析,总体设计要全面分析聊天室系统的架构。

通过这次设计,使我们认识到体系的架构是最重要的,只有准确的系统设计、很好的定义各个模块及模块之间的关系,才能在编码阶段更轻松的的实现。

通过这次课程设计,对我们的逻辑思维能力是一个很大的锻炼,它不仅加强了我们的系统思考问题的能力,而且还改变了我们以前不好的编程习惯,虽然花费了不少的时间,但是我们学到了丰富的知识。

另外,此次课程设计也提高了我们的团对合作精神,让我们明白不是不能一个人能单独完成,而是要集思广益,结合更多的人的创意思维。

让我们大家深刻的体会到理论与实际相结合的重要性与微妙之处。

对于不同的想法我们都会集中讨论并对好的意见加以借鉴,在这个讨论的过程中,还更正了不少我们各自自身对于某个知识点的误区。

这次程序设计也是一个毅力的考验过程。

有时候往往只是一个小小的错误,却要花出几小时甚至是一两天的时间才可能发现它。

所以在这个过程不能过于急躁,要很有耐心将程序反复调试。

Appimport .*;import .*;import .*;public class AppServer extends Thread {private ServerSocket serverSocket;private ServerFrame sFrame;private static Vector userOnline = new Vector(1, 1);private static Vector v = new Vector(1, 1);public AppServer() {sFrame = new ServerFrame();try {serverSocket = new ServerSocket(1001);.");(); dd(pnlLogin);lblServer = new JLabel("服务器(S):");lblUserName = new JLabel("用户名(U):");lblPassword = new JLabel("口令(P):");txtServer = new JTextField(20);("");txtUserName = new JTextField(20);pwdPassword = new JPasswordField(20);btnLogin = new JButton("登录(L)");("登录到服务器");('L');btnRegister = new JButton("注册(R)");("注册新用户");('R');btnExit = new JButton("退出(X)");("退出系统");('X');(null);(new Color(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);Font fontstr = new Font("宋体", , 12); (fontstr);(fontstr);(fontstr);(fontstr);(fontstr);(fontstr);(fontstr);(fontstr);(fontstr);;;;;;(lblServer);(txtServer);(lblUserName);(txtUserName);(lblPassword);(pwdPassword);(btnLogin);(btnRegister);(btnExit);Icon logo1 = new ImageIcon("images\\"); lblLogo = new JLabel(logo1);(0, 0, 340, 66);(lblLogo);setResizable(false);setSize(340, 260);setVisible(true);scrnsize = ();setLocation / 2 - () / 2,/ 2 - () / 2);Image img = ("images\\");setIconImage(img);(this);(this);(this);@SuppressWarnings({ "deprecation", "static-access" })public void actionPerformed(ActionEvent ae) {Object source = ();if (btnLogin)) {if ().equals("")|| ().equals("")) {JOptionPane op1 = new JOptionPane();(null, "用户名或密码不能为空");} else {strServerIp = ();login();}}if (btnRegister)) {strServerIp = ();();new Register(strServerIp);}if (source == btnExit) {(0);}}@SuppressWarnings("deprecation")public void login() {Customer data = new Customer();= ();= ();try {Socket toServer;toServer = new Socket(strServerIp, 1001);ObjectOutputStream streamToServer = new ObjectOutputStream(toServer .getOutputStream());((Customer) data);BufferedReader fromServer = new BufferedReader(new InputStreamReader()));String status = ();if ("登录成功")) {new ChatRoom((String) , strServerIp);();();();();} else {(null, status);();();();}} catch (ConnectException e1) {(null, "未能建立到指定服务器的连接!");} catch (InvalidClassException e2) {(null, "类错误!");} catch (NotSerializableException e3) {(null, "对象未序列化!");} catch (IOException e4) {(null, "不能写入到指定服务器!");}}public static void main(String args[]) {new Login();}}import *;public class Register extends JFrame implements ActionListener {private JComboBox comboBox;private static final long serialVersionUID = 902180L;JPanel pnlRegister;JLabel lblUserName,lblGender,lblAge;JLabel lblPassword,lblConfirmPass,lblEmail,logoPosition;JTextField txtUserName,txtAge,txtEmail;JPasswordField pwdUserPassword,pwdConfirmPass;JRadioButton rbtnMale,rbtnFemale;ButtonGroup btngGender;JButton btnOk,btnCancel,btnClear;String strServerIp;final JLabel headLabel = new JLabel();Dimension scrnsize;Toolkit toolkit=();public Register(String ip){super("[HappyChat]聊天室注册窗口");strServerIp=ip;pnlRegister=new JPanel();().add(pnlRegister);lblUserName=new JLabel("用户名:");lblGender=new JLabel("性别:");lblAge=new JLabel("年龄:");lblPassword=new JLabel("口令:");lblConfirmPass=new JLabel("确认口令:");lblEmail=new JLabel("电子邮件:");txtUserName=new JTextField(30);txtEmail=new JTextField(30);txtAge=new JTextField(10);pwdUserPassword=new JPasswordField(30);pwdConfirmPass=new JPasswordField(30);rbtnMale=new JRadioButton("男",true);rbtnFemale=new JRadioButton("女");btngGender=new ButtonGroup();btnOk=new JButton("确定(O)");('O');("保存注册信息");btnCancel=new JButton("返回(B)");('B');("返回登录窗口");btnClear=new JButton("清空(L)");('L');("清空注册信息");(null);(new Color(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);Font fontstr=new Font("宋体",,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);(pwdUserPassword);(pwdConfirmPass);(btnOk);(btnCancel);(btnClear);(rbtnMale);(rbtnFemale);(rbtnMale);(rbtnFemale);Icon logo = new ImageIcon("images\\");logoPosition = new JLabel(logo);(0, 0, 360,78);(logoPosition);(360,313);(true);(false);scrnsize=();()/2,()/2);Image img=("images\\");(img);btnOk .addActionListener(this);(this);btnClear .addActionListener(this);final JLabel label = new JLabel();("头像:");(30, 120, 60, 15);(label);comboBox = new JComboBox();(true);(new DefaultComboBoxModel(new String[] {"1", "2", "3"}));(110, 116, 47, 23);(new ItemListener() {public void itemStateChanged(ItemEvent arg0) {Icon logo = new ImageIcon("face\\"+().toString()+".jpg");(logo);}});(comboBox);;oString();if {(null,"用户名不能为空");return;}if {(null,"密码不能为空");return;}if(! {(null,"密码两次输入不一致,请重新输入");return;}if {(null,"年龄不能为空");return;}int age=());if (age<=0||age>100){(null,"年龄输入不合法");return;}int Found_flag=0;for (int i=0;i< {if'@'){Found_flag++;}}if(Found_flag!=1){(null,"电子邮箱格式不正确,请重新输入");return;}try{Socket toServer;toServer = new Socket(strServerIp,1001);ObjectOutputStream streamToServer=new ObjectOutputStream ());((Register_Customer)data);BufferedReader fromServer=new BufferedReader(new InputStreamReader()));String status=();JOptionPane op=new JOptionPane();(null,status);if+"注册成功")){("");("");("");("");("");}();();}catch(InvalidClassException e1){(null,"类错误!");}catch(NotSerializableException e2){(null,"对象未序列化!");}catch(IOException e3){(null,"不能写入到指定服务器!");}}public static void main(String args[]){new Register("");}}public ChatRoom(String name, String ip) {dd(pnlChat);Font fntDisp1 = new Font("宋体", , 12);String list[] = { "所有人" };btnCls = new JButton("清屏(C)");btnExit = new JButton("退出(X)");btnSend = new JButton("发送(N)");btnSave = new JButton("保存(S)");btnTimer = new JButton("时钟(T)");lblUserList = new JLabel("【在线用户列表】");lblUserMessage = new JLabel("【聊天信息】");lblSendMessage = new JLabel("聊天内容:");lblChatUser = new JLabel("你对:");lblUserTotal = new JLabel("在线人数:");lblCount = new JLabel("0");lstUserList = new txtMessage = new JTextField(170);cmbUser = new JComboBox(list);etScreenSize();Dimension fra=();if>{=;}if>{=;}( show();i nt delay = 1000;A ctionListener taskPerformer = new ActionListener(){public void actionPerformed(ActionEvent evt){repaint();}};n ew Timer(delay, taskPerformer).start();}public void actionPerformed(ActionEvent e){();}public void paint( Graphics g ){Insets insets = getInsets();int L0 = /2, T0 = /2;int hh,mm,ss;String st;h=getSize().height;;(L0+30,T0+30,h-60,h-60);(L0+32,T0+32,h-64,h-64);r=h/2-30;x0=30+r-5+L0;y0=30+r-5-T0;ang=60;for (int i=1; i<=12; i++){x=(int)((r+10)*(RAD*ang)+x0);y=(int)((r+10)*(RAD*ang)+y0);(""+i,x,h-y);ang-=30;}x0=30+r+L0; y0=30+r+T0;Calendar now=();hh=;mm=;ss=;;(L0,T0,60,28);;if (hh < 10) st="0"+hh; else st=""+hh;if (mm < 10) st=st+":0"+mm; else st=st+":"+mm;if (ss < 10) st=st+":0"+ss; else st=st+":"+ss;(st,L0,T0+25);sdo=90-ss*6;mdo=90-mm*6;hdo=90-hh*30-mm/2;if (old_X > 0){(getBackground());(x0,y0,old_X,(h-old_Y));} else{old_M=mdo;old_H=hdo;};x=(int)((r-8)*(RAD*sdo)+x0);y=(int)((r-8)*(RAD*sdo)+y0)-2*T0;(x0,y0,x,(h-y));old_X=x;old_Y=y;if (mdo != old_M){line(g,old_M,(int)(r*,getBackground());old_M=mdo;}if (hdo != old_H){line(g,old_H,(int)(r*,getBackground());old_H=hdo;}line(g,mdo,(int)(r*,;line(g,hdo,(int)(r*,;}public void line(Graphics g, int t, int n, Color c) {int [] xp = new int[4];int [] yp = new int[4];xp[0]=x0;yp[0]=y0;xp[1]= (int)((n-10)*(RAD*(t-4))+x0);yp[1]=h-(int)((n-10)*(RAD*(t-4))+y0);xp[2]= (int)( n *(RAD* t )+x0);yp[2]=h-(int)( n *(RAD* t )+y0);xp[3]= (int)((n-10)*(RAD*(t+4))+x0);yp[3]=h-(int)((n-10)*(RAD*(t+4))+y0);(c);(xp,yp,4);}public static void main(String args[]){new Clock();}}。

相关主题