java网络聊天室课程设计报告(内附代码)

更新时间:2024-07-02 15:00:02 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

课程设计

网络聊天室

一、 设计内容及要求 二、设计原始资料 1)电子工业出版社《JSP实用教程》,郑阿奇编著 2)电子工业出版社《JAVA程序设计实用教程》,叶核亚编著 三、设计完成后提交的文件和图表 1.计算说明书部分 JSP界面设计

2.图纸部分: 程序流程图 四、进程安排 五、主要参考资料 1)电子工业出版社《JSP实用教程》,郑阿奇编著 2)电子工业出版社《JAVA程序设计实用教程》,叶核亚编著考资料

成 绩 评 定 表

作品成绩 报告成绩 口试(答辩)成绩 总评成绩

目 录

课程设计概述 ............................................................................................................................... 3 1.1问题描述 ............................................................................................................................. 3 1.2功能需求分析 ..................................................................................................................... 3 1.3环境需求分析 ..................................................................................................................... 3 学生信息管理系统软件总体设计 ............................................................................................... 4 2.1整体思路 ............................................................................................................................. 4 2.2总体设计流程图 ................................................................................................................. 5 学生信息管理软件详细设计 ....................................................................................................... 6 3.1.界面设计 ............................................................................................................................. 6 3.2通信功能实现方法 ............................................................................................................. 8 参考文献 ..................................................................................................................................... 45

摘要

私達の実践の能力を高めるため、学んだ知識を運用することができて行って更に創造して、学校は特に2週間手配して、私達にVisual C++の課程の設計の実習を行わせます.

このフ?イルの詳しい説明はVisual C++6.0環境の下で、1つのソフトウェ?の過程を設計して、このソフトウェ?は各種のデータの個数を統計したのです。

このソフトウェ?の機能は、ユーザーは1段の文字を入力して、ソフトウェ?は文字の中の各類のデータの数を記録して、英文のデータの数、数字のデータの数、空欄のデータの数とそれのタイプのデータの数を含んで、そしてそれらを明らかに示します.

以下、課程を通して説明を設計して、データはソフトウェ?の説明を統計して、プログラムは説明を調整して、総括などの方面を開発して、詳しくこのプログラムの製作の過程を説明して、作用、各種の実行することができる操作.

关键字:データの統計,VC++6.0, ヘッドフ?イル

课程设计概述

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整体思路

该C/S模式的聊天系统,就是服务器来提供服务端连接响应,客户端主动的发起连接请求。当多个用户同时连接到服务器时,经由服务器的接收与转发便可以实现客户之间的通信。

对于整体系统的流程,也是分为两部分,即客户端的发起请求,服务器响应请求。首先是客户端的登陆,客户端在登陆时,必须设置所想要连接的服务器,然后客户端就会根据设置的服务器IP地址,向服务器发起建立连接请求。而服务器端是始终在监听网络状态的,主要检测到有一个连接请求,那么服务器就会给当前的发起端分配一个服务线程,用于处理它的各种请求。

对于客户端的各种请求,实际上都是通过在客户发往服务器的各种字符流区分的,具体的方法就是在消息的头部以及尾部添加特殊字符串,从而实现服务器对消息请求的识别。比如对于登陆信息,消息的头部就是“PEOPLO”,而对于私聊中的消息,头部就是“SEC”,其他的同理都添加了头部。当然,对于客户端来说,这些都是透明的,用户的操作并没有受到任何影响。在服务器端,消息被检测分析后,变回根据具体的目的进行处理,比如是私聊消息,服务器便会根据其尾部的目的信息,向目标端转发该条消息。

这里额外要说的是,该系统特别的对用户发来的消息进行了加密处理,即用户的各种具体信息,不仅能够防止向第三方的泄漏,而且即使服务器端出现异常,信息也不会泄漏。

对于私聊的方式,该系统所采用的方法类似于QQ的通信方式,由发起方主动连接,当目的方接收到连接请求后,会主动建立一个私聊窗口,从而 实现私聊。

2.2总体设计流程图

OutputStream InputStream 接收请求后创建socket连接 等待并接收 Server Client 建立服务器 建立连接 创建socket

开始通信 InputStream OutputStream 关闭socket 结束通信 关闭socket

学生信息管理软件详细设计

3.1.界面设计

由于这里界面设计源代码比较简单,这里不再列出。 3.1.1 服务器界面设计

服务器界面

3.1.2客户端界面设计

登陆界面

注册界面

聊天室界面

3.2通信功能实现方法

列举部分实现通信功能的主要代码

AppServer.java文件

public class AppServer extends Thread {

private static Vector userOnline = new Vector(1, 1); private ServerFrame sFrame; private ServerSocket serverSocket;

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(\);

} catch (IOException e) { }

sFrame.txtStatus.setText(\已启动...\); this.start(); // 启动线程

fail(e, \不能启动服务!\);

/**

* 退出服务器 *

* @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(\

} 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;

JLabel lblStatus, lblNumber, lblMax, lblServerName, lblProtocol, // 服务器信息面板

JPanel pnlServer, pnlServerInfo;

lblIP,

lblPort, lblLog;

public JTextField txtStatus, txtNumber, txtMax, txtServerName,

txtProtocol, txtIP,

JTextField txtNotice; JScrollPane spUser; JList lstUser;

public JLabel lblMessage, lblUser, lblNotice, lblUserCount; // 用户信息面板 JPanel pnlUser;

public TextArea taMessage; JTabbedPane tpServer; public TextArea taLog; JButton btnStop, btnSaveLog;

txtPort;

JButton btnSend, btnKick;

public String ti = \;

public String serverMessage =\;

public ServerFrame() {

// 服务器窗口

super(\聊天服务器\); setSize(550, 500);

setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setResizable(false); Dimension scr =

Toolkit.getDefaultToolkit().getScreenSize();// 在屏幕居中显示

// ==========服务器信息面板=========================

Dimension fra = this.getSize(); if (fra.width > scr.width) { }

if (fra.height > scr.height) { }

this.setLocation((scr.width - fra.width) / 2,

(scr.height - fra.height) / 2); fra.height = scr.height; fra.width = scr.width;

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(\人\, 10); txtNumber.setEditable(false);

lblMax = new JLabel(\最多在线人数:\); txtMax = new JTextField(\人\, 10); txtMax.setEditable(false);

lblServerName = new JLabel(\服务器名称:\); txtServerName = new JTextField(10); txtServerName.setEditable(false);

lblProtocol = new JLabel(\访问协议:\);

txtProtocol = new JTextField(\, 10); txtProtocol.setEditable(false);

lblIP = new JLabel(\服务器IP:\); txtIP = new JTextField(10); txtIP.setEditable(false);

lblPort = new JLabel(\服务器端口:\); txtPort = new JTextField(\, 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);//指定的固定单元格宽度值,而不

是从列表元素计算而来的宽度值

spUser.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

pnlUser.add(lblMessage); pnlUser.add(taMessage);

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);

spUser.getViewport().setView(lstUser);

spUser = new JScrollPane();

lstUser.setFixedCellHeight(18);

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 {

FileOutputStream fileoutput = new

FileOutputStream(\,

protected void tiRen() { }

true);

String temp = taMessage.getText();

fileoutput.write(temp.getBytes()); fileoutput.close();

JOptionPane.showMessageDialog(null, \记录保存在log.txt\);

} catch (Exception e) { }

System.out.println(e);

}

}

// TODO 自动生成方法存根

ti = list.getSelectedValue().toString(); log(\+ti);

private void log(String string) { }

// TODO 自动生成方法存根

String newta = taMessage.getText(); newta += (\+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 userOnline;

/** * 聊天信息 */

private Vector userChat;

/**

* 从客户到服务器 输入流 */

private ObjectInputStream fromClient;

/**

* 传到客户端 打印流 */

private PrintStream toClient;

/**

* 注册用户列表

*/

private static Vector vList = new Vector(); /** * 临时对象 */

private Object obj;

/**

* 服务器日志窗体 */

private ServerFrame sFrame;

@SuppressWarnings(\) /**

* 创建与客户端通讯 */

public Connection(ServerFrame frame, Socket client, Vector u, Vector c) {

netClient = client; userOnline = u; userChat = c; sFrame = frame; try {

// 发生双向通信

// 检索客户输入 fromClient = new

ObjectInputStream(netClient.getInputStream());

/**

* 处理与客户端的通讯线程 */

public void run() {

try {// obj是Object类的对象

obj = (Object) fromClient.readObject();

if (obj.getClass().getName().equals(\)) {

serverLogin();

}

// 服务器写到客户

toClient = new PrintStream(netClient.getOutputStream());

} catch (IOException e) { }

this.start();

try {

netClient.close();

} catch (IOException e1) { }

System.out.println(\不能建立流\ + e1); return;

//

{

}

serverLoginDB();

if (obj.getClass().getName().equals(\))

//

serverRegiste(); serverRegisteDB();

}

if (obj.getClass().getName().equals(\)) { }

if (obj.getClass().getName().equals(\)) { }

if (obj.getClass().getName().equals(\)) { }

serverExit(); serverChat(); serverMessage();

} 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(\) public void serverLogin() {

try {

Customer clientMessage2 = (Customer) obj;

// 读文件

FileInputStream file3 = new FileInputStream(\); ObjectInputStream objInput1 = new

ObjectInputStream(file3);

int find = 0; // 查找判断标志 // System.out.println(find);

for (int i = 0; i < vList.size(); i++) {

Register_Customer reg = (Register_Customer)

vList = (Vector) objInput1.readObject(); 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++) {

// chenmin

String _custName = ((Customer) userOnline if

.elementAt(a)).custName;

(clientMessage2.custName.equals(_custName)) {

if (userOnline.size() >= 50) {

toClient.println(\登录人数过多,请稍候再试

}

}

login_flag = 1; break;

\);

}

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() + freshServerUserList();

break;

} else { toClient.println(\该用户已登录\);

}

}

} else { continue;

}

}

if (find == 0) {

toClient.println(\没有这个用户,请先注册\);

}

}

file3.close(); objInput1.close(); fromClient.close();

} catch (ClassNotFoundException e) {

System.out.println(e);

} catch (IOException e) { }

System.out.println(e);

/** * * 登录处理 *

* @throws Exception */

@SuppressWarnings(\) public void serverLoginDB() {

try {

Customer clientMessage2 = (Customer) obj;

String name = clientMessage2.custName;

String pass = clientMessage2.custPassword;

String sql = \* from yonghu where custName='\ + name

+ \;

if (!login) {

toClient.println(\密码不正确\);

ResultSet rs = DB.executeQuery(sql); System.out.println(\ + sql); boolean login = false; String head=\; while (rs.next()) { }

System.out.println(\+login);

String ps=rs.getString(\).toString(); System.out.println(\+ps+\); System.out.println(\+pass+\); if (ps.equals(pass.toString())) { }

System.out.println(\+ps.compareTo(pass)); head=rs.getString(\);

System.out.println(\+rs.getString(\));

login = true;

System.out.println(\);

}

return;

// 判断是否已经登录 int login_flag = 0;

for (int a = 0; a < userOnline.size(); a++) {

String _custName = ((Customer)

userOnline.elementAt(a)).custName;

if (login_flag == 0) {

System.out.println(\+head); clientMessage2.custHead =head;//

if (userOnline.size() >= 50) { }

toClient.println(\登录人数过多,请稍候再试\); return;

}

if (clientMessage2.custName.equals(_custName)) { }

login_flag = 1; break;

getUserHeadByName(clientMessage2.custName);

userOnline.addElement(clientMessage2);

toClient.println(\登录成功\); Date t = new Date();

log(\用户\ + clientMessage2.custName + \登录成功,\ + \

登录时间:\

/**

* 刷新服务器日志窗体在线列表 * */

private void freshServerUserList() {

String[] userList = new String[50]; }

fromClient.close();

+ t.toLocaleString() + \);

freshServerUserList(); return;

} else { }

toClient.println(\该用户已登录\);

} catch (Exception e) { }

e.printStackTrace();

Customer cus = null;

for (int j = 0; j < userOnline.size(); j++) { }

sFrame.list.setListData(userList); sFrame.txtNumber.setText(\ + userOnline.size()); sFrame.lblUserCount.setText(\当前在线人数:\ +

cus = (Customer) userOnline.get(j); userList[j] = cus.custName;

userOnline.size());

/** * 注册处理 */

@SuppressWarnings( { \, \ }) public void serverRegiste() {

try {

int flag = 0; // 是否重名判断标志

Register_Customer clientMessage = (Register_Customer) obj; File fList = new File(\);

if (fList.length() != 0)// 判断是否是第一个注册用户 {

ObjectInputStream objInput = new ObjectInputStream(

new FileInputStream(fList));

}

// System.out.println(\

}

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); // 将向量中的类写回文件

FileOutputStream file = new FileOutputStream(fList); ObjectOutputStream objout = new

ObjectOutputStream(file);

objout.writeObject(vList);

// 发送注册成功信息

toClient.println(clientMessage.custName + \注册成功\); Date t = new Date();

log(\用户\ + clientMessage.custName + \注册成功, \ + \

注册时间:\

/** * 注册处理 */

@SuppressWarnings( { \, \ }) public void serverRegisteDB() {

try {

int flag = 0; // 是否重名判断标志

}

}

+ t.toLocaleString() + \);

file.close(); objout.close(); fromClient.close();

} catch (ClassNotFoundException e) {

System.out.println(e);

} catch (IOException e) { }

System.out.println(e);

Register_Customer clientMessage = (Register_Customer) obj;

String sql = \

+ clientMessage.custName + \;

ResultSet rs = DB.executeQuery(sql); System.out.println(\ + sql); boolean reg = false; while (rs.next()) { }

System.out.println(\+reg); if (reg) { }

toClient.println(\注册名重复,请另外选择\); return; reg = true;

ResultSetMetaData rsmd = rs.getMetaData(); int numberOfColumns = rsmd.getColumnCount(); for(int i=1;i<=numberOfColumns;i++){ }

System.out.println();

String me=rsmd.getColumnName(i); String v=rs.getString(i); System.out.println(me+\+v);

本文来源:https://www.bwwdw.com/article/cuz.html

Top