综合项目

Posted luodongyang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了综合项目相关的知识,希望对你有一定的参考价值。

 

 

 

 

 

 

 

 

 

Java课程设计

(综合项目文档)

 

多人聊天室

 

 

 

 

 

 

 

二〇二〇


   

1 绪论 1

1.1 项目概述 1

1.2 项目意义 1

2 开发工具和相关技术简介 2

2.1 Eclipse 2

2.2 Java语言介绍 2

3 系统需求分析 4

3.1 系统可行性分析 4

3.2 系统需求分析 4

3.3 组内成员分工 4

3.4 项目进度安排 5

4 系统设计 6

4.1 系统设计 6

5 系统实现 8

6 系统测试 10

7 结论和心得 11

 


1 绪论

1.1 项目概述

聊天室:使用图形用户界面,能实现一个聊天室中多人聊天,能收到发送的内容,有客户端与服务器。

1.2 项目意义

用团队合作的方式,来锻炼同学们动手能力,独立思考的能力和团队合作的能力,并且能很好的巩固Java知识

考验分析能力:1.要对项目进行概念分析,分析项目相对于客户,要怎么样才能达到满意。2.必要性分析。3.需求分析,考虑到用户需要什么样的功能,要怎么简单的去实现它,才能使用户满意

通过此次项目,使我们能更好的了解概念和掌握开发方法,提高自己的运用能力和自身的编程能力。
2 开发工具和相关技术简介

项目多人聊天界面。开发环境:Eclipse;开发语言:Java语言

2.1 Eclipse简介或者MyEclipse或者IEDA简介)

开发工具:Eclipse

Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具Java Development KitJDK)。

Eclipse最初是由IBM公司开发的替代商业软件Visual Age for Java的下一代IDE开发环境200111月贡献给开源社区,它由非营利软件供应商联盟Eclipse基金会(Eclipse Foundation)管理。2003年,Eclipse 3.0选择OSGi服务平台规范为运行时架构。20076月,稳定版3.3发布;20086月发布代号为Ganymede3.4版;20096月发布代号为Galileo3.5版;20106月发布代号为Helios3.6版;20116月发布代号为Indigo3.7版;20126月发布代号为Juno4.2版;20136月发布代号为Kepler4.3版;20146月发布代号为Luna4.4版;20156月项目发布代号为Mars4.5版。

2.2 Java语言介绍

Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程

Java具有简单性、面向对象、分布式健壮性安全性、平台独立与可移植性、多线程、动态性等特点 Java可以编写桌面应用程序Web应用程序分布式系统嵌入式系统应用程序等

2009年,甲骨文公司宣布收购Sun  2010年,Java编程语言的共同创始人之一詹姆斯·高斯林从Oracle公司辞职。2011年,甲骨文公司举行了全球性的活动,以庆祝Java7的推出,随后Java7正式发布。2014年,甲骨文公司发布了Java8正式版

 

 


3 系统需求分析

3.1 系统可行性分析

  1. 技术可行性

本次程序运用所需软件为eclipse,采用的Java语言,所以技术上是可行的。

  1. 经济可行性

本次程序所使用的eclipse软件是免费的,我们不需要额外的开销,经济上是可行的

  1. 操作可行性

本次程序运用了简单的用户键盘录入操作,简单易懂,很好操作,因此在操作上是可行的

 

3.2 系统需求分析

仿照QQ运行界面,实现账号登录、界面聊天、好友上线功能、服务器。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

3.3 组内成员分工

3-1 组内成员分工情况表

序号

姓名

组内角色

小组分工

备注

1

罗东杨

项目经理

写代码

 

2

王卓

编码师

写代码

 

3

刘嘉豪

测试员

写文档 写代码

 负责小组文档

4

齐书纬

构架师

找资料 写代码

找图片 和视频资料

说明:组内角色:组长为项目经理;其他人分别为编码、测试、架构师等。

3.4 进度安排

进度安排如表3-2所示。

3-2 进度安排表

阶段

持续时间

阶段描述

输出

构思阶段

1天

需求分析

需求说明,功能模块图

设计阶段

1天

系统设计

设计说明

是现阶段

3天

编写代码

项目工程源代码

1天

系统测试

进行黑盒测试(功能测试)

运行阶段

1天

部署、运行

系统使用说明、运维报告-答辩

 

 

 


4 系统设计

4.1 系统设计

设计类似QQ聊天的界面

思想来源:

登录界面:

 

聊天界面:

通过对QQ的分析得到了启发 可以根据仿照QQ去实现

系统实现

 

 

package qqclient;

 

/**

 * 这是客户端和服务器端保持通讯的线程.

 */

import java.io.ObjectInputStream;

import java.net.Socket;

 

import qqserver.Message;

import qqserver.MessageType;

public class ClientConServerThread extends Thread {

private Socket s;

//构造函数

public ClientConServerThread(Socket s){

this.s=s;

}

public void run(){

while(true){

//不停的读取从服务器端发来的消息

try {

ObjectInputStream ois=new ObjectInputStream(s.getInputStream());

Message m=(Message)ois.readObject();

/* System.out.println("读取到从服务发来的消息"+ m.getSender() +" "+m.getGetter()+" 内容"+

m.getCon());*/

if(m.getMesType().equals(MessageType.message_comm_mes)){

//把从服务器获得消息,显示到该显示的聊天界面

QqChat qqChat=ManageQqChat.getQqChat(m.getGetter()+" "+m.getSender());

//显示

qqChat.showMessage(m);

}else if(m.getMesType().equals(MessageType.message_ret_onLineFriend)){

System.out.println("客户端接收到"+m.getCon());

String con=m.getCon();

String friends[]=con.split(" ");

String getter=m.getGetter();

System.out.println("getter="+getter);

//修改相应的好友列表.

QqFriendList qqFriendList=ManageQqFriendList.getQqFriendList(getter);

 

// if(qqFriendList)

//更新在线好友.

if(qqFriendList!=null){

qqFriendList.upateFriend(m);

}

}

} catch (Exception e) {

e.printStackTrace();

// TODO: handle exception

}

}

}

public Socket getS() {

return s;

}

public void setS(Socket s) {

this.s = s;

}

}

 

 

package qqclient;

 

/**

 * 这是一个管理客户端和服务器保持通讯的线程类

 */

import java.util.HashMap;

public class ManageClientConServerThread {

private static HashMap hm=new HashMap<String, ClientConServerThread>();

//把创建好的ClientConServerThread放入到hm

public static void addClientConServerThread(String qqId,ClientConServerThread ccst){

hm.put(qqId, ccst);

}

//可以通过qqId取得该线程

public static ClientConServerThread getClientConServerThread(String qqId){

return (ClientConServerThread)hm.get(qqId);

}

}

 

 

 

 

package qqclient;

 

/**

 * 这是一个管理用户聊天界面的类

 */

import java.util.HashMap;

public class ManageQqChat {

private static HashMap hm=new HashMap<String, QqChat>();

//加入

public static void addQqChat(String loginIdAnFriendId,QqChat qqChat){

hm.put(loginIdAnFriendId, qqChat);

}

//取出

public static QqChat getQqChat(String loginIdAnFriendId ){

return (QqChat)hm.get(loginIdAnFriendId);

}

 

}

 

 

 

package qqclient;

 

/**

 * 管理好友、黑名单..界面类

 */

import java.util.HashMap;

public class ManageQqFriendList {

private static HashMap hm=new HashMap<String, QqFriendList>();

public static void addQqFriendList(String qqid,QqFriendList qqFriendList){

hm.put(qqid, qqFriendList);

}

public static QqFriendList getQqFriendList(String qqId){

return (QqFriendList)hm.get(qqId);

}

}

 

 

 

 

 

package qqclient;

 

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.ObjectOutputStream;

 

import javax.swing.ImageIcon;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JTextArea;

import javax.swing.JTextField;

 

import qqserver.Message;

import qqserver.MessageType;

public class QqChat extends JFrame implements ActionListener{

 

JTextArea jta;

JTextField jtf;

JButton jb;

JPanel jp;

String ownerId;

String friendId;

public static void main(String[] args) {

// TODO Auto-generated method stub

//QqChat qqChat=new QqChat("1");

}

public QqChat(String ownerId,String friend){

this.ownerId=ownerId;

this.friendId=friend;

jta=new JTextArea();

jtf=new JTextField(15);

jb=new JButton("发送");

jb.addActionListener(this);

jp=new JPanel();

jp.add(jtf);

jp.add(jb);

this.add(jta,"Center");

this.add(jp,"South");

this.setTitle(ownerId+" 正在和 "+friend+" 聊天");

this.setIconImage((new ImageIcon("image/qq.gif").getImage()));

this.setSize(300, 200);

this.setVisible(true);

}

//写一个方法,让它显示消息

public void showMessage(Message m){

String info=m.getSender()+" "+m.getGetter()+" :"+m.getCon()+" ";

this.jta.append(info);

}

public void actionPerformed(ActionEvent arg0) {

// TODO Auto-generated method stub

if(arg0.getSource()==jb){

//如果用户点击了,发送按钮

Message m=new Message();

m.setMesType(MessageType.message_comm_mes);

m.setSender(this.ownerId);

m.setGetter(this.friendId);

m.setCon(jtf.getText());

m.setSendTime(new java.util.Date().toString());

//发送给服务器.

try {

ObjectOutputStream oos=new ObjectOutputStream

(ManageClientConServerThread.getClientConServerThread(ownerId).getS().getOutputStream());

oos.writeObject(m);

} catch (Exception e) {

e.printStackTrace();

// TODO: handle exception

}

}

 

}

 

}

 

 

 

 

package qqclient;

 

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.net.Socket;

 

import qqserver.Message;

import qqserver.User;

public class QqClientConServer {

public  Socket s;

//发送第一次请求

public boolean sendLoginInfoToServer(Object o){

boolean b=false;

try {

System.out.println("服务器运行");

s=new Socket("127.0.0.1",9999);

ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());

oos.writeObject(o);

ObjectInputStream ois=new ObjectInputStream(s.getInputStream());

Message ms=(Message)ois.readObject();

//这里就是验证用户登录的地方

if(ms.getMesType().equals("1")){

//就创建一个该qq号和服务器端保持通讯连接得线程

ClientConServerThread ccst=new ClientConServerThread(s);

//启动该通讯线程

ccst.start();

ManageClientConServerThread.addClientConServerThread

(((User)o).getUserId(), ccst);

b=true;

}else{

//关闭Scoket

s.close();

}

} catch (Exception e) {

e.printStackTrace();

// TODO: handle exception

}finally{

}

return b;

}

public void SendInfoToServer(Object o){

}

}

 

 

 

package qqclient;

/**

 功能:qq客户端登录界面

 */

import java.awt.Color;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.io.ObjectOutputStream;

import javax.swing.*;

import qqserver.Message;

import qqserver.MessageType;

import qqserver.User;

public class QqClientLogin extends JFrame implements ActionListener{

//定义北部需要的组件

JLabel jbl1; //用于放北部的图片背景

//定义中部需要的组件

JTabbedPane jtp;

JPanel jp2,jp3,jp4; //分别用于设置 北部 中部 南部

JLabel jp2_jbl1,jp2_jbl2;

JTextField jp2_jtf;

JPasswordField jp2_jpf;

JCheckBox jp2_jcb1,jp2_jcb2;

//定义南部需要的组件

JPanel jp1;

JButton jp1_jb1,jp1_jb2,jp1_jb3;

public static void main(String[] args) {

// TODO Auto-generated method stub

QqClientLogin qqClientLogin=new QqClientLogin();

}

public QqClientLogin(){

//处理北部

jbl1=new JLabel(new ImageIcon("image/tou.gif"));

//处理中部

jp2=new JPanel(new GridLayout(3,2));

jp2_jbl1=new JLabel("Q Q 号 码",JLabel.CENTER);

jp2_jbl2=new JLabel("Q Q 密 码",JLabel.CENTER);

//jp2_jbl3.setForeground(Color.blue);

jp2_jtf=new JTextField();

jp2_jpf=new JPasswordField();

jp2_jcb1=new JCheckBox("隐身登录");

jp2_jcb2=new JCheckBox("记住密码");

//把控件按照顺序加入到jp2

jp2.add(jp2_jbl1);

jp2.add(jp2_jtf);

jp2.add(jp2_jbl2);

jp2.add(jp2_jpf);

jp2.add(jp2_jcb1);

jp2.add(jp2_jcb2);

//创建选项卡窗口

jtp=new JTabbedPane();

jtp.add("QQ号码",jp2);

jp3= new JPanel();

jtp.add("手机号码",jp3);

jp4=new JPanel();

jtp.add("电子邮件",jp4);

//处理南部

jp1=new JPanel();

jp1_jb1=new JButton(new ImageIcon("image/denglu.gif"));

//响应用户点击登录

jp1_jb1.addActionListener(this);

jp1_jb2=new JButton(new ImageIcon("image/quxiao.gif"));

jp1_jb3=new JButton(new ImageIcon("image/xiangdao.gif"));

//把三个按钮放入到jp1

jp1.add(jp1_jb1);

jp1.add(jp1_jb2);

jp1.add(jp1_jb3);

this.add(jbl1,"North");

this.add(jtp,"Center");

//..jp1放在南部

this.add(jp1,"South");

this.setSize(350, 240);

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.setVisible(true);

}

public void actionPerformed(ActionEvent arg0) {

// TODO Auto-generated method stub

//如果用户点击登录

if(arg0.getSource()==jp1_jb1){

QqClientUser qqClientUser=new QqClientUser();

User u=new User();

u.setUserId(jp2_jtf.getText().trim());

u.setPasswd(new String(jp2_jpf.getPassword()));

if(qqClientUser.checkUser(u)){

try {

//把创建好友列表的语句提前.

QqFriendList qqList=new QqFriendList(u.getUserId());

ManageQqFriendList.addQqFriendList(u.getUserId(), qqList);

//发送一个要求返回在线好友的请求包.

ObjectOutputStream oos=new ObjectOutputStream

(ManageClientConServerThread.getClientConServerThread(u.getUserId()).getS().getOutputStream());

//做一个Message

Message m=new Message();

m.setMesType(MessageType.message_get_onLineFriend);

//指明我要的是这个qq号的好友情况.

m.setSender(u.getUserId());

oos.writeObject(m);

} catch (Exception e) {

e.printStackTrace();

// TODO: handle exception

}

 

 

 

//关闭掉登录界面

this.dispose();

}else{

JOptionPane.showMessageDialog(this,"用户名密码错误");

}

}

}

 

}

 

 

 

 

package qqclient;

import qqserver.User;

public class QqClientUser {

public boolean checkUser(User u){

return new QqClientConServer().sendLoginInfoToServer(u);

}

}

 

 

 

 

 

package qqclient;

import java.awt.BorderLayout;

import java.awt.CardLayout;

import java.awt.Color;

import java.awt.GridLayout;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.MouseEvent;

import java.awt.event.MouseListener;

 

import javax.swing.ImageIcon;

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

 

import qqserver.Message;

public class QqFriendList extends JFrame implements ActionListener,MouseListener{

//处理第一张卡片.

JPanel jphy1,jphy2,jphy3;

JButton jphy_jb1,jphy_jb2,jphy_jb3;

JScrollPane jsp1;

String owner;

//处理第二张卡片(陌生人).

JPanel jpmsr1,jpmsr2,jpmsr3;

JButton jpmsr_jb1,jpmsr_jb2,jpmsr_jb3;

JScrollPane jsp2;

JLabel []jb1s;

//把整个JFrame设置成CardLayout

CardLayout cl;

public static void main(String[] args) {

// TODO Auto-generated method stub

// QqFriendList qqFriendList=new QqFriendList();

}

//更新在线的好友情况

public void upateFriend(Message m){

String onLineFriend[]=m.getCon().split(" ");

for(int i=0;i<onLineFriend.length;i++){

jb1s[Integer.parseInt(onLineFriend[i])-1].setEnabled(true);

}

}

public QqFriendList(String ownerId){

this.owner=ownerId;

//处理第一张卡片(显示好友列表)

jphy_jb1=new JButton("我的好友");

jphy_jb2=new JButton("陌生人");

jphy_jb2.addActionListener(this);

jphy_jb3=new JButton("黑名单");

jphy1=new JPanel(new BorderLayout());

//假定有50个好友

jphy2=new JPanel(new GridLayout(50,1,4,4));

//jphy2,初始化50好友.

jb1s =new JLabel[50];

for(int i=0;i<jb1s.length;i++){

jb1s[i]=new JLabel(i+1+"",new ImageIcon("image/mm.jpg"),JLabel.LEFT);

jb1s[i].setEnabled(false);

if(jb1s[i].getText().equals(ownerId)){

jb1s[i].setEnabled(true);

}

jb1s[i].addMouseListener(this);

jphy2.add(jb1s[i]);

}

jphy3=new JPanel(new GridLayout(2,1));

//把两个按钮加入到jphy3

jphy3.add(jphy_jb2);

jphy3.add(jphy_jb3);

jsp1=new JScrollPane(jphy2);

//jphy1,初始化

jphy1.add(jphy_jb1,"North");

jphy1.add(jsp1,"Center");

jphy1.add(jphy3,"South");

//处理第二张卡片

 

jpmsr_jb1=new JButton("我的好友");

jpmsr_jb1.addActionListener(this);

jpmsr_jb2=new JButton("陌生人");

jpmsr_jb3=new JButton("黑名单");

jpmsr1=new JPanel(new BorderLayout());

//假定有20个陌生人

jpmsr2=new JPanel(new GridLayout(10,1,4,4));

//jphy2,初始化20陌生人.

JLabel []jb1s2=new JLabel[10];

for(int i=0;i<jb1s2.length;i++){

jb1s2[i]=new JLabel(i+1+"",new ImageIcon("image/mm.jpg"),JLabel.LEFT);

jpmsr2.add(jb1s2[i]);

}

jpmsr3=new JPanel(new GridLayout(2,1));

//把两个按钮加入到jphy3

jpmsr3.add(jpmsr_jb1);

jpmsr3.add(jpmsr_jb2);

jsp2=new JScrollPane(jpmsr2);

//jphy1,初始化

jpmsr1.add(jpmsr3,"North");

jpmsr1.add(jsp2,"Center");

jpmsr1.add(jpmsr_jb3,"South");

cl=new CardLayout();

this.setLayout(cl);

this.add(jphy1,"1");

this.add(jpmsr1,"2");

//在窗口显示自己的编号.

this.setTitle(ownerId);

this.setSize(300, 500);

this.setVisible(true);

}

 

public void actionPerformed(ActionEvent arg0) {

// TODO Auto-generated method stub

//如果点击了陌生人按钮,就显示第二张卡片

if(arg0.getSource()==jphy_jb2){

cl.show(this.getContentPane(), "2");

}else if(arg0.getSource()==jpmsr_jb1){

cl.show(this.getContentPane(), "1");

}

}

public void mouseClicked(MouseEvent arg0) {

// TODO Auto-generated method stub

//响应用户双击的事件,并得到好友的编号.

if(arg0.getClickCount()==2)

{

//得到该好友的编号

String friendNo=((JLabel)arg0.getSource()).getText();

//System.out.println("你希望和 "+friendNo+" 聊天");

QqChat qqChat=new QqChat(this.owner,friendNo);

//把聊天界面加入到管理类

ManageQqChat.addQqChat(this.owner+" "+friendNo, qqChat);

}

}

public void mouseEntered(MouseEvent arg0) {

JLabel jl=(JLabel)arg0.getSource();

jl.setForeground(Color.red);

}

public void mouseExited(MouseEvent arg0) {

JLabel jl=(JLabel)arg0.getSource();

jl.setForeground(Color.black);

}

public void mousePressed(MouseEvent arg0) {

}

public void mouseReleased(MouseEvent arg0) {

}

}

 

 

 

package qqserver;

import java.util.HashMap;

import java.util.Iterator;

public class ManageClientThread {

public static HashMap hm=new HashMap<String, SerConClientThread>();

//hm中添加一个客户端通讯线程

public static  void addClientThread(String uid,SerConClientThread ct){

hm.put(uid, ct);

}

public static SerConClientThread getClientThread(String uid){

return (SerConClientThread)hm.get(uid);

}

//返回当前在线的人的情况

public static String getAllOnLineUserid(){

//使用迭代器完成

Iterator it=hm.keySet().iterator();

String res="";

while(it.hasNext()){

res+=it.next().toString()+" ";

}

return res;

}

}

 

 

package qqserver;

public class Message implements java.io.Serializable{

private String mesType;

private String sender;

private String getter;

private String con;

private String sendTime;

public String getSender() {

return sender;

}

public void setSender(String sender) {

this.sender = sender;

}

public String getGetter() {

return getter;

}

public void setGetter(String getter) {

this.getter = getter;

}

public String getCon() {

return con;

}

public void setCon(String con) {

this.con = con;

}

public String getSendTime() {

return sendTime;

}

public void setSendTime(String sendTime) {

this.sendTime = sendTime;

}

public String getMesType() {

return mesType;

}

public void setMesType(String mesType) {

this.mesType = mesType;

}

}

 

package qqserver;

/**

 * 定义包的种类

 */

public interface MessageType {

String message_succeed="1";//表明是登陆成功

String message_login_fail="2";//表明登录失败

String message_comm_mes="3";//普通信息包

String message_get_onLineFriend="4";//要求在线好友的包

String message_ret_onLineFriend="5";//返回在线好友的包

}

 

 

 

package qqserver;

 

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.net.ServerSocket;

import java.net.Socket;

public class MyQqServer {

public MyQqServer(){

try {

//9999监听

System.out.println("我是服务器,在9999监听");

ServerSocket ss=new ServerSocket(9999);

//阻塞,等待连接

while(true){

Socket s=ss.accept();

//接收客户端发来的信息.

ObjectInputStream ois=new ObjectInputStream(s.getInputStream());

User u=(User)ois.readObject();

System.out.println("服务器接收到用户id:"+u.getUserId()+"  密码:"+u.getPasswd());

Message m=new Message();

ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());

if(u.getPasswd().equals("123456")){

//返回一个成功登陆的信息报

m.setMesType("1");

oos.writeObject(m);

//这里就单开一个线程,让该线程与该客户端保持通讯.

SerConClientThread scct=new SerConClientThread(s);

ManageClientThread.addClientThread(u.getUserId(), scct);

//启动与该客户端通信的线程.

scct.start();

//并通知其它在线用户.

scct.notifyOther(u.getUserId());

}else{

m.setMesType("2");

oos.writeObject(m);

//关闭Socket

s.close();

}

}

} catch (Exception e) {

e.printStackTrace();

// TODO: handle exception

}finally{

}

}

}

 

 

package qqserver;

 

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

/**

 * 这是服务器端的控制界面,可以完成启动服务器,关闭服务器

 * 可以管理和监控用户.

 */

import javax.swing.JButton;

import javax.swing.JFrame;

import javax.swing.JPanel;

public class MyServerFrame extends JFrame implements ActionListener {

JPanel jp1;

JButton jb1,jb2;

public static void main(String[] args) {

// TODO Auto-generated method stub

MyServerFrame mysf=new MyServerFrame();

}

public MyServerFrame(){

jp1=new JPanel();

jb1=new JButton("启动服务器");

jb1.addActionListener(this);

jb2=new JButton("关闭服务器");

jp1.add(jb1);

jp1.add(jb2);

this.add(jp1);

this.setSize(500, 400);

this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

this.setVisible(true);

}

public void actionPerformed(ActionEvent arg0) {

// TODO Auto-generated method stub

if(arg0.getSource()==jb1){

new MyQqServer();

}

}

}

 

 

 

package qqserver;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.net.Socket;

/**

 * 功能:是服务器和某个客户端的通信线程

 */

import java.util.HashMap;

import java.util.Iterator;

public class SerConClientThread  extends Thread{

Socket s;

public SerConClientThread(Socket s){

//把服务器和该客户端的连接赋给s

this.s=s;

}

//让该线程去通知其它用户

public void notifyOther(String iam){

//得到所有在线的人的线程

HashMap hm=ManageClientThread.hm;

Iterator it=hm.keySet().iterator();

while(it.hasNext()){

Message m=new Message();

m.setCon(iam);

m.setMesType(MessageType.message_ret_onLineFriend);

//取出在线人的id

String onLineUserId=it.next().toString();

try {

ObjectOutputStream oos=new ObjectOutputStream(ManageClientThread.getClientThread(onLineUserId).s.getOutputStream());

m.setGetter(onLineUserId);

oos.writeObject(m);

} catch (Exception e) {

e.printStackTrace();

// TODO: handle exception

}

}

}

public void run(){

while(true){

//这里该线程就可以接收客户端的信息.

try {

ObjectInputStream ois=new ObjectInputStream(s.getInputStream());

Message m=(Message)ois.readObject();

// System.out.println(m.getSender()+" "+m.getGetter()+" :"+m.getCon());

//对从客户端取得的消息进行类型判断,然后做相应的处理

if(m.getMesType().equals(MessageType.message_comm_mes)){

//一会完成转发.

//取得接收人的通信线程

SerConClientThread sc=ManageClientThread.getClientThread(m.getGetter());

ObjectOutputStream oos=new ObjectOutputStream(sc.s.getOutputStream());

oos.writeObject(m);

}else if(m.getMesType().equals(MessageType.message_get_onLineFriend)){

System.out.println(m.getSender()+" 要他的好友");

//把在服务器的好友给该客户端返回.

String res=ManageClientThread.getAllOnLineUserid();

Message m2=new Message();

m2.setMesType(MessageType.message_ret_onLineFriend);

m2.setCon(res);

m2.setGetter(m.getSender());

ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());

oos.writeObject(m2);

}

} catch (Exception e) {

e.printStackTrace();

// TODO: handle exception

}

}

 

 

}

}

package qqserver;

/**

 * 这是用户信息类

 */

public class User implements java.io.Serializable {

private String userId;

private String passwd;

public String getUserId() {

return userId;

}

public void setUserId(String userId) {

this.userId = userId;

}

public String getPasswd() {

return passwd;

}

public void setPasswd(String passwd) {

this.passwd = passwd;

}

}

 

 

 

系统测试

主要对聊天项目的登录,好友界面,服务器,聊天界面块进行测试,测试结果如表6-1所示。

6-1 花盆监控模块测试表

编号

测试功能

输入描述

预期结果

运行结果

HP01

登录

输入账号,密码

点击登录按钮

跳到好友列表

正常,与预期结果一致

HP02

聊天

双击好友

写好信息后,点发送按钮

好友收到发送的信息

正常,与预期结果一致

HP03

好友上线

好友登录

 

好友头像有灰色变为彩色

正常,与预期结果一致

登录界面,聊天界面,好友界面均测试成功。

主要是对该课题设计并实现的所有功能模块进行测试,并给出测试表格和验证结果。结果表明本课题经过测试,所有功能都符合需求分析并且均能正常实现。

 

7 结论和心得

罗东杨的心得:

通过此次课程设计,使我更加扎实的掌握了有关Java方面的知识,在设计过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。实践出真知,通过亲自动手制作,使我们掌握的知识不再是纸上谈兵。 过而能改,善莫大焉。在课程设计过程中,我们不断发现错误,不断改正,不断领悟,不断获取。最终的检测调试环节,本身就是在践行过而能改,善莫大焉的知行观。这次课程设计终于顺利完成了,在设计中遇到了很多问题,最后在老师的指导下,终于游逆而解。在今后社会的发展和学习实践过程中,一定要不懈努力,不能遇到问题就想到要退缩,一定要不厌其烦的发现问题所在,然后一一进行解决,只有这样,才能成功的做成想做的事,才能在今后的道路上劈荆斩棘

王卓的心得:

兴趣,感觉学习工作中兴趣很关键,只是一个引发人积极性的问题,有了兴趣就自觉了,效率自然就高了。再次要敢于尝试和挑战。不要安于现成的程序,而且不要害怕失败,在程序调试的过程中这点尤为重要,发现出问题然后解决问题是一个积累经验的过程,而且很高效。最后要不懈追求。对于源代码进行不断的完善,要尽可能的实现课题所要求的功能。对于初学者或者开发较少的人来说,大量大写程序还是有必要的,但同时要注意思考,理解其实现的内在意义。还可以自己添加一些有意义的功能来实现。当看到自己编写的程序正常运行时,兴趣也会随之而来,乐此不疲,形成一个良性循环。

刘嘉豪的心得:

我从这次的设计中还感受到坚持的重要性。做事情不能轻言谈放弃,虽然过程不顺利,与想象中相去甚远。但是只要我们能坚持,朝着自己既定的目标前进,就一定会走到终点。一点小小的挫折实际上是在为最后的美景做铺垫,当我们守得云开见月明的时候,就会发现,沿途的曲折其实是在考验我们的目标是否坚定。坚持下来,我们会收获丰硕的果实。

齐书纬的心得:

原本我们之间只是各自编程,没有多少交流,通过本次实训,我们发现一开始编好的代码放在一起有时无法运行,通过几天的讨论研究学习,我们改良了一次又一次代码,推翻了一个又一个方案,最终确定下来了最好的方案,很有成就感

以上是关于综合项目的主要内容,如果未能解决你的问题,请参考以下文章

阶段二,综合项目

综合项目报告

综合项目

Hadoop综合项目——二手房统计分析(起始篇)

全国PPP综合信息平台项目管理库2020年2月报

关注全国PPP综合信息平台项目管理库2020年2月报