课程设计网络聊天室院(系) 别信电学院班级计算102学号姓名指导教师时间2013-4-18—2013-5-10课程设计任务书题目网络聊天室课程设计系(部) 信电学院专业计算机科学与技术班级计算102学生姓名学号4 月18 日至5 月10 日共 4 周指导教师(签字)系主任(签字)年月日成绩评定表目录课程设计概述 (1)1、1问题描述 (1)1、2功能需求分析 (1)1、3环境需求分析 (1)学生信息管理系统软件总体设计 (2)2、1整体思路 (2)2、2总体设计流程图 (2)学生信息管理软件详细设计 (3)3、1、界面设计 (3)3、2通信功能实现方法 (6)参考文献........................................................................................................错误!未定义书签。
课程设计概述1、1问题描述`随着计算机网络日新月异的发展,人们的交流方式越来越多,传统的交流方式,如:信件、电报、电话等已经难以满足人们的交流要求,在互联网上即时的与好友取得联系,已经成为当今社会人们主流的联系方式。
因此,两台计算机之间进行即时通讯、发送文件等交流方式已经成为必然潮流。
因此出现了QQ等聊天工具,然而QQ等聊天工具虽然方便、实用,但就是,娱乐功能太多,有很多吸引人的娱乐功能,从一定程度上来说,就是一种娱乐工具,不能作为用于即时通讯、文件共享的专用工具。
目前,用于实现单一的即时通讯、文件共享的软件实在太少,而且,它们中大部分都就是绝对的C/S模式,对远程服务器有非常大的依赖性,没有彻底实现点对点的交流。
为此,我决定开发一个专用于实现两台计算机之间即时通讯、文件共享的软件,以方便两台计算机之间信息的交流。
避免了服务器忙或与服务器无法连接时,浪费过多时间用于与服务器建立连接。
因此,这个软件就是极具适应性与实用性的即时通讯软件。
1、2功能需求分析实现网络聊天的功能,采用Windows Socket(或Java Socket)编程,服务器与客户端采用了TCP/IP连接方式,在设计聊天方案时,可将所有信息发往服务器端,再由服务器进行处理,服务器端就是所有信息的中心。
服务器端要保存用户信息,可利用数据库来实现这一功能,需要建立用户信息数据库。
在客户端可采用文件系统保存聊天纪录与用户号码。
可通过闪动托盘图标与播放不同的音乐提示信息到来及好友上线等信息。
可通过建立消息链表来保存用户接收的各种消息。
1、3环境需求分析运行环境:Windows 9x、2000、XP、Windows 7必要环境:JDK 1、6以上、eclipse开发环境硬件环境:CPU 400MHz以上,内存512MB以上学生信息管理系统软件总体设计2、1整体思路服务器界面3、1、2客户端界面设计登陆界面注册界面聊天室界面3、2通信功能实现方法列举部分实现通信功能的主要代码AppServer、java文件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);/*** 创建服务器启动服务监听1001端口**/public AppServer() {sFrame = new ServerFrame();try {serverSocket = new ServerSocket(1001);// 获取服务器的主机名与IP地址InetAddress address = InetAddress、getLocalHost();sFrame、txtServerName、setText(address、getHostName());sFrame、txtIP、setText(address、getHostAddress());sFrame、txtPort、setText("1001");} catch (IOException e) {fail(e, "不能启动服务!");}sFrame、txtStatus、setText("已启动、、、");this、start(); // 启动线程}/*** 退出服务器** @param e* 异常* @param str* 退出信息*/public static void fail(Exception e, String str) {System、out、println(str + " 。
" + e);}/*** 监听客户的请求,当有用户请求时创建 Connection线程*/public void run() {try {while (true) {// 监听并接受客户的请求Socket client = serverSocket、accept();new Connection(sFrame, client, userOnline, v); // 支持多线程// System、out、println("userLength:"+userLength);}} catch (IOException e) {System、out、println("不能监听");}}/*** 启动服务器*/public static void main(String args[]) {new AppServer();}}ServerFrame、java文件public class ServerFrame extends JFrame implements ActionListener {public JList list;/****/private static final long serialVersionUID =-8936397327038098620L;// 服务器信息面板JPanel pnlServer, pnlServerInfo;JLabel lblStatus, lblNumber, lblMax, lblServerName, lblProtocol, lblIP,lblPort, lblLog;public JTextField txtStatus, txtNumber, txtMax, txtServerName, txtProtocol, txtIP,txtPort;JButton btnStop, btnSaveLog;public TextArea taLog;JTabbedPane tpServer;public TextArea taMessage;// 用户信息面板JPanel pnlUser;public JLabel lblMessage, lblUser, lblNotice, lblUserCount;JList lstUser;JScrollPane spUser;JTextField txtNotice;JButton btnSend, btnKick;public String ti = "";public String serverMessage ="";public ServerFrame() {// 服务器窗口super("[HappyChat]聊天服务器");setSize(550, 500);setDefaultCloseOperation(JFrame、EXIT_ON_CLOSE);setResizable(false);Dimension scr = Toolkit、getDefaultToolkit()、getScreenSize();// 在屏幕居中显示Dimension fra = this、getSize();if (fra、width > scr、width) {fra、width = scr、width;}if (fra、height > scr、height) {fra、height = scr、height;}this、setLocation((scr、width - fra、width) / 2,(scr、height - fra、height) / 2);// ==========服务器信息面板=========================pnlServer = new JPanel();pnlServer、setLayout(null);pnlServerInfo = new JPanel(new GridLayout(14, 1));pnlServerInfo、setBorder(BorderFactory、createCompoundBorder(BorderFactory、createTitledBorder(""), BorderFactory、createEmptyBorder(1, 1, 1, 1)));lblStatus = new JLabel("当前状态:");txtStatus = new JTextField(10);txtStatus、setEditable(false);lblNumber = new JLabel("当前在线人数:");txtNumber = new JTextField("0 人", 10);txtNumber、setEditable(false);lblMax = new JLabel("最多在线人数:");txtMax = new JTextField("50 人", 10);txtMax、setEditable(false);lblServerName = new JLabel("服务器名称:");txtServerName = new JTextField(10);txtServerName、setEditable(false);lblProtocol = new JLabel("访问协议:");txtProtocol = new JTextField("HTTP", 10); txtProtocol、setEditable(false);lblIP = new JLabel("服务器IP:");txtIP = new JTextField(10);txtIP、setEditable(false);lblPort = new JLabel("服务器端口:");txtPort = new JTextField("8000", 10);txtPort、setEditable(false);btnStop = new JButton("关闭服务器(C)");btnStop、addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { closeServer();}});lblLog = new JLabel("[服务器日志]");taLog = new TextArea(20, 50);btnSaveLog = new JButton("保存日志(S)"); btnSaveLog、addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { saveLog();}});pnlServerInfo、add(lblStatus);pnlServerInfo、add(txtStatus); pnlServerInfo、add(lblNumber); pnlServerInfo、add(txtNumber); pnlServerInfo、add(lblMax);pnlServerInfo、add(txtMax);pnlServerInfo、add(lblServerName); pnlServerInfo、add(txtServerName); pnlServerInfo、add(lblProtocol); pnlServerInfo、add(txtProtocol); pnlServerInfo、add(lblIP);pnlServerInfo、add(txtIP);pnlServerInfo、add(lblPort);pnlServerInfo、add(txtPort);pnlServerInfo、setBounds(5, 5, 100, 400); lblLog、setBounds(110, 5, 100, 30);taLog、setBounds(110, 35, 400, 370); btnStop、setBounds(200, 410, 120, 30); btnSaveLog、setBounds(320, 410, 120, 30); pnlServer、add(pnlServerInfo);pnlServer、add(lblLog);pnlServer、add(taLog);pnlServer、add(btnStop);pnlServer、add(btnSaveLog);// ===========在线用户面板==================== pnlUser = new JPanel();pnlUser、setLayout(null);lblMessage = new JLabel("[用户消息]");taMessage = new TextArea(20, 20);lblNotice = new JLabel("通知:");txtNotice = new JTextField(20);btnSend = new JButton("发送(S)");btnSend、setEnabled(true);btnSend、addActionListener(new ActionListener() {public void actionPerformed(ActionEvent arg0) {serverMessage();}});lblUserCount = new JLabel("在线总人数 0 人");btnKick = new JButton("踢人(K)");btnKick、addActionListener(new ActionListener() {public void actionPerformed(ActionEvent arg0) {tiRen();}});lblUser = new JLabel("[在线用户列表]");lstUser = new JList();lstUser、setVisibleRowCount(17);lstUser、setFixedCellWidth(180);//指定的固定单元格宽度值,而不就是从列表元素计算而来的宽度值lstUser、setFixedCellHeight(18);spUser = new JScrollPane();spUser、setVerticalScrollBarPolicy(JScrollPane、VERTICAL_SCROLLBAR_ALWAYS);spUser、getViewport()、setView(lstUser);lblMessage、setBounds(5, 5, 100, 25);taMessage、setBounds(5, 35, 300, 360);lblUser、setBounds(310, 5, 100, 25);spUser、setBounds(310, 35, 220, 360);lblNotice、setBounds(5, 410, 40, 25);txtNotice、setBounds(50, 410, 160, 25);btnSend、setBounds(210, 410, 80, 25);lblUserCount、setBounds(320, 410, 100, 25);btnKick、setBounds(440, 410, 80, 25);pnlUser、add(lblMessage);pnlUser、add(taMessage);pnlUser、add(lblUser);pnlUser、add(spUser);list = new JList();list、setListData(new String[] { "" });spUser、setViewportView(list);pnlUser、add(lblNotice);pnlUser、add(txtNotice);pnlUser、add(btnSend);pnlUser、add(lblUserCount);pnlUser、add(btnKick);// ============主标签面板======================== tpServer = new JTabbedPane(JTabbedPane、TOP);tpServer、add("服务器管理", pnlServer);tpServer、add("用户信息管理", pnlUser);this、getContentPane()、add(tpServer);setVisible(true);}protected void serverMessage() {// TODO自动生成方法存根this、serverMessage = txtNotice、getText();txtNotice、setText("");}protected void closeServer() {// TODO自动生成方法存根this、dispose();//this、res}protected void saveLog() {// TODO自动生成方法存根try {= new ("log、txt",true);String temp = taMessage、getText();(temp、getBytes());();JOptionPane、showMessageDialog(null, "记录保存在log、txt");} catch (Exception e) {System、out、println(e);}}protected void tiRen() {// TODO自动生成方法存根ti = list、getSelectedValue()、toString();log("Ti:"+ti);}private void log(String string) {// TODO自动生成方法存根String newta = taMessage、getText();newta += ("\n"+string);taMessage、setText(newta);}public void actionPerformed(ActionEvent evt) {}public static void main(String args[]) {new ServerFrame();}}Connection、java文件public class Connection extends Thread {/*** 与客户端通讯Socket*/private Socket netClient;/*** 在线用户列表*/private Vector<Customer> userOnline;/*** 聊天信息*/private Vector<Chat> userChat;/*** 从客户到服务器输入流*/private ObjectInputStream fromClient;/*** 传到客户端打印流*/private PrintStream toClient;/*** 注册用户列表*/private static Vector vList = new Vector(); /*** 临时对象*/private Object obj;/*** 服务器日志窗体*/private ServerFrame sFrame;@SuppressWarnings("unchecked")/*** 创建与客户端通讯*/public Connection(ServerFrame frame, Socket client, Vector u, Vector c) {netClient = client;userOnline = u;userChat = c;sFrame = frame;try {// 发生双向通信// 检索客户输入fromClient = new ObjectInputStream(netClient、getInputStream());// 服务器写到客户toClient = new PrintStream(netClient、getOutputStream());} catch (IOException e) {try {netClient、close();} catch (IOException e1) {System、out、println("不能建立流" + e1);return;}}this、start();}/*** 处理与客户端的通讯线程*/public void run() {try {// obj就是Object类的对象obj = (Object) fromClient、readObject();if (obj、getClass()、getName()、equals("Customer")) { // serverLogin();serverLoginDB();}if (obj、getClass()、getName()、equals("Register_Customer")) {// serverRegiste();serverRegisteDB();}if (obj、getClass()、getName()、equals("Message")) { serverMessage();if (obj、getClass()、getName()、equals("Chat")) { serverChat();}if (obj、getClass()、getName()、equals("Exit")) { serverExit();}} catch (IOException e) {System、out、println(e);} catch (ClassNotFoundException e1) {System、out、println("读对象发生错误!" + e1);} finally {try {netClient、close();} catch (IOException e) {System、out、println(e);}}}/**** 登录处理*/@SuppressWarnings("deprecation")public void serverLogin() {Customer clientMessage2 = (Customer) obj;// 读文件file3 = new ("user、txt");ObjectInputStream objInput1 = newObjectInputStream(file3);vList = (Vector) objInput1、readObject();int find = 0; // 查找判断标志// System、out、println(find);for (int i = 0; i < vList、size(); i++) {Register_Customer reg = (Register_Customer) vList、elementAt(i);if (reg、custName、equals(clientMessage2、custName)) {find = 1;if (!reg、custPassword、equals(clientMessage2、custPassword)) {toClient、println("密码不正确");break;} else {// 判断就是否已经登录int login_flag = 0;for (int a = 0; a < userOnline、size(); a++) {// chenminString _custName = ((Customer) userOnline、elementAt(a))、custName;if (clientMessage2、custName、equals(_custName)) {login_flag = 1;break;}}if (userOnline、size() >= 50) {toClient、println("登录人数过多,请稍候再试");break;}if (login_flag == 0) {clientMessage2、custHead = reg、head;// getUserHeadByName(clientMessage2、custName);userOnline、addElement(clientMessage2);toClient、println("登录成功");Date t = new Date();log("用户" + clientMessage2、custName + "登录成功,"+ "登录时间:" + t、toLocaleString() + "\n");freshServerUserList();break;} else {toClient、println("该用户已登录");}}} else {continue;}}if (find == 0) {toClient、println("没有这个用户,请先注册");}();objInput1、close();fromClient、close();} catch (ClassNotFoundException e) {System、out、println(e);} catch (IOException e) {System、out、println(e);}}/**** 登录处理** @throws Exception*/@SuppressWarnings("deprecation")public void serverLoginDB() {try {Customer clientMessage2 = (Customer) obj;String name = clientMessage2、custName;String pass = clientMessage2、custPassword;String sql = "select * from yonghu where custName='"+ name + "'";ResultSet rs = DB、executeQuery(sql);System、out、println("sql:" + sql);boolean login = false;String head="";while (rs、next()) {String ps=rs、getString("custPassword")、toString();System、out、println("ps:["+ps+"]");System、out、println("pass:["+pass+"]");if (ps、equals(pass、toString())) {login = true;System、out、println("logined:");}System、out、println("compareTo:"+ps、compareTo(pass));head=rs、getString("head");System、out、println("head:"+rs、getString("head"));}System、out、println("login:"+login);if (!login) {toClient、println("密码不正确");return;}// 判断就是否已经登录int login_flag = 0;for (int a = 0; a < userOnline、size(); a++) {String _custName = ((Customer) userOnline、elementAt(a))、custName;if (clientMessage2、custName、equals(_custName)) {login_flag = 1;break;}}if (userOnline、size() >= 50) {toClient、println("登录人数过多,请稍候再试");return;}if (login_flag == 0) {System、out、println("head:"+head);clientMessage2、custHead =head;// getUserHeadByName(clientMessage2、custName);userOnline、addElement(clientMessage2);toClient、println("登录成功");Date t = new Date();log("用户" + clientMessage2、custName + "登录成功," + "登录时间:"+ t、toLocaleString() + "\n");freshServerUserList();return;} else {toClient、println("该用户已登录");}fromClient、close();} catch (Exception e) {e、printStackTrace();}}/*** 刷新服务器日志窗体在线列表**/private void freshServerUserList() {String[] userList = new String[50];Customer cus = null;for (int j = 0; j < userOnline、size(); j++) {cus = (Customer) userOnline、get(j);userList[j] = cus、custName;}sFrame、list、setListData(userList);sFrame、txtNumber、setText("" + userOnline、size());sFrame、lblUserCount、setText("当前在线人数:" + userOnline、size());// System、out、println("fresh ok");}/*** 注册处理*/@SuppressWarnings( { "unchecked", "deprecation" })public void serverRegiste() {try {int flag = 0; // 就是否重名判断标志Register_Customer clientMessage = (Register_Customer) obj;= new File("user、txt");if (fList、length() != 0)// 判断就是否就是第一个注册用户{ObjectInputStream objInput = new ObjectInputStream(new (fList));vList = (Vector) objInput、readObject();// 判断就是否有重名for (int i = 0; i < vList、size(); i++) {Register_Customer reg = (Register_Customer) vList、elementAt(i);if (reg、custName、equals(clientMessage、custName)) {toClient、println("注册名重复,请另外选择");flag = 1;break;} else if (reg、custName、equals("所有人")) {toClient、println("禁止使用此注册名,请另外选择");flag = 1;break;}}}if (flag == 0) {// 添加新注册用户vList、addElement(clientMessage);// 将向量中的类写回文件file = new (fList);ObjectOutputStream objout = newObjectOutputStream(file);objout、writeObject(vList);// 发送注册成功信息toClient、println(clientMessage、custName + "注册成功");Date t = new Date();log("用户" + clientMessage、custName + "注册成功, " + "注册时间:"+ t、toLocaleString() + "\n");();objout、close();fromClient、close();}} catch (ClassNotFoundException e) {System、out、println(e);} catch (IOException e) {System、out、println(e);}}/*** 注册处理*/@SuppressWarnings( { "unchecked", "deprecation" })public void serverRegisteDB() {try {int flag = 0; // 就是否重名判断标志Register_Customer clientMessage = (Register_Customer) obj;String sql = "select * from yonghu where custName='"+ clientMessage、custName + "'";ResultSet rs = DB、executeQuery(sql);System、out、println("sql:" + sql);boolean reg = false;while (rs、next()) {reg = true;ResultSetMetaData rsmd = rs、getMetaData();int numberOfColumns = rsmd、getColumnCount();for(int i=1;i<=numberOfColumns;i++){String me=rsmd、getColumnName(i);String v=rs、getString(i);System、out、println(me+":"+v);}System、out、println();}System、out、println("reg:"+reg);if (reg) {toClient、println("注册名重复,请另外选择");return;}if (clientMessage、custName、equals("所有人")) {toClient、println("禁止使用此注册名,请另外选择");return;}sql = "insert intoyonghu(custName,custPassword,age,sex,email,head) values('"+ clientMessage、custName+ "','"+ clientMessage、custPassword+ "','"+ clientMessage、age+ "','"+ clientMessage、sex+ "','"+ clientMessage、email+ "','" + clientMessage、head + "')";System、out、println("c:"+sql);DB、executeUpdate(sql);toClient、println(clientMessage、custName + "注册成功");Date t = new Date();log("用户" + clientMessage、custName + "注册成功, " + "注册时间:"+ t、toLocaleString() + "\n");fromClient、close();} catch (Exception e) {e、printStackTrace();System、out、println(e);}}/*** 发送信息处理*/public void serverMessage() {try {Message mess = new Message();mess、userOnLine = userOnline;mess、chat = userChat;mess、ti = sFrame、ti;mess、serverMessage = "" + sFrame、serverMessage;ObjectOutputStream outputstream = new ObjectOutputStream(netClient、getOutputStream());outputstream、writeObject((Message) mess);netClient、close();outputstream、close();} catch (IOException e) {}}/*** 增加信息处理*/public void serverChat() {// 将接收到的对象值赋给聊天信息的序列化对象Chat cObj = new Chat();cObj = (Chat) obj;// chenmincObj、chatMessage = WordFilter、filter(cObj、chatMessage);chatLog(cObj);// 将聊天信息的序列化对象填加到保存聊天信息的矢量中userChat、addElement((Chat) cObj);return;}/*** 用户退出处理*/@SuppressWarnings("deprecation")public void serverExit() {Exit exit = new Exit();exit = (Exit) obj;removeUser(exit);// chenminif (sFrame、ti、equals(exit、exitname)) {sFrame、ti = "";}Date t = new Date();log("用户" + exit、exitname + "已经退出, " + "退出时间:" + t、toLocaleString());freshServerUserList();}/*** 在线用户中删除退出用户** @param exit* 退出用户名对象*/private void removeUser(Exit exit) {// TODO自动生成方法存根Vector<Customer> vec = new Vector<Customer>();Customer _cus = null;for (int j = 0; j < userOnline、size(); j++) {_cus = (Customer) userOnline、get(j);if (!exit、exitname、equals(_cus、custName)) {vec、add(_cus);}// System、out、println("list:"+_cus、custName);}userOnline、removeAllElements();for (int j = 0; j < vec、size(); j++) {_cus = (Customer) vec、get(j);userOnline、add(_cus);}}/*** 日志服务器窗体写信息** @param log* 日志信息*/public void log(String log) {String newlog = sFrame、taLog、getText() + "\n" + log;sFrame、taLog、setText(newlog);}/**** 日志服务器窗体写聊天信息*** 聊天信息对象*/@SuppressWarnings("deprecation")public void chatLog(Chat obj) {String newlog = sFrame、taMessage、getText();Date date = new Date();if (!obj、whisper) {newlog += "\n";newlog += ("[" + date、toLocaleString() + "]");newlog += obj、chatUser;newlog += "->";newlog += obj、chatToUser;newlog += ":";newlog += obj、chatMessage;}String text = "";text += obj、chatUser;text += "->";text += obj、chatToUser;text += ":";text += obj、chatMessage;String sql ="insert into logs(text,shijian)values('"+text+"','"+date、toLocaleString()+"')";try {System、out、println(sql);DB、executeUpdate(sql);} catch (Exception e) {// TODO Auto-generated catch blocke、printStackTrace();}sFrame、taMessage、setText(newlog);}}设计体会及今后的改进意见为了提高我们的实践能力,让我们学以致用,能灵活运用所学的知识进行再创造,学校特安排我们进行为期二周的Visual C++课程设计实习,并安排了指导老师帮助辅导,让我们在规范化、严谨化、实用化上面有了很大进展。