# Java 课设
## 网络聊天程序
## 第一章
开发环境:Intelij IDEA 和 JDK8
## 第二章业务分析
用 JavaSocket 编程开发聊天室
1. 用 Java 图形用户界面编写聊天室服务器端和客户端, 支持多个客户端连接到一个服务器。每个客户端能够输入账号。
2. 可以实现群聊(聊天记录显示在所有客户端界面)。
3. 完成好友列表在各个客户端上显示。
4. 可以实现私人聊天,用户可以选择某个其他用户,单独发送信息。
5. 服务器能够群发系统消息,能够强行让某些用户下线。
6. 客户端的上线下线要求能够在其他客户端上面实时刷新。
说明:
1.客户端和服务端都用 swing 做成图形界面
2.客户端与服务端都可以用Socket进行通信
3.客户端和服务端都实现Runnable接口,开启线程。
4.通过流将数据封装,通过用户名对不同用户进行区别
## 第三章 系统设计
1. 系统功能定义
服务端的代码在 Server.java 文件中
public void run() 用来对用户的登录进行监听,如果用户上线,服务器端就会有用户登录信息。
public void actionPerformed(ActionEvent e) 有两个 JButton 会用到这个方法,一个功能是对客户端发送消息,另一个是踢人
public void handleAll() 功能是群发
public void handleExpel() 功能是踢人
public void sendMessage(String msg)功能是对所用用户进行发送 msg,Server.java 中还有一个类 ChatThread 功能是开启一个线程,对每个事件进行判断,看是否是踢人,群发,还是私聊,这里会用到一个 switch case 语句
客户端的代码在Client.ava中
public void run() 开启线程,处理消息
public void actionPerformed(ActionEvent e) 处理鼠标点击事件
public void handleSS() 在私聊窗口中发消息
public void handleSend() 群发消息
public void handleSec(String name) 建立私聊窗口
2. 关键问题设计
最关键的是 Client.java 中的 public void run()的设计
```java
public void run() {//客户端与服务器端发消息的线程
while (true) {
try {
String msg = br.readLine();//读取服务器是否发送了消息给该客户端
String[] strs = msg.split("#");
//判断是否为服务器发来的登陆信息
if (strs[0].equals("LOGIN")) {
if (!strs[1].equals(nickName)) {//不是本人的上线消息就显示,本人的不显示
jta.append(strs[1] + "上线啦!\n");
dl.addElement(strs[1]);//DefaultListModel来更改JList的内容
userList.repaint();
}
} else if (strs[0].equals("MSG")) {//接到服务器发送消息的信息
if (!strs[1].equals(nickName)) {//别人说的
jta.append(strs[1] + "说:" + strs[2] + "\n");
} else {
jta.append("我说:" + strs[2] + "\n");
}
} else if (strs[0].equals("USERS")) {//USER消息,为新建立的客户端更新好友列表
dl.addElement(strs[1]);
userList.repaint();
} else if (strs[0].equals("ALL")) {
jta.append("系统消息:" + strs[1] + "\n");
} else if (strs[0].equals("OFFLINE")) {
if (strs[1].equals(nickName)) {//如果是自己下线的消息,说明被服务器端踢出聊天室,强制下线
JOptionPane.showMessageDialog(this, "您已被系统请出聊天室!");
System.exit(0);
}
jta.append(strs[1] + "下线啦!\n");
dl.removeElement(strs[1]);
userList.repaint();
} else if ((strs[2].equals(nickName) || strs[1].equals(nickName)) && strs[0].equals("SMSG")) {
if (!strs[1].equals(nickName)) {
jTextArea.append(strs[1] + "说:" + strs[3] + "\n");
jta.append("系统提示:" + strs[1] + "私信了你" + "\n");
} else {
jTextArea.append("我说:" + strs[3] + "\n");
}
} else if ((strs[2].equals(nickName) || strs[1].equals(nickName)) && strs[0].equals("FSMSG")) {
sender = strs[1];
receiver = strs[2];
//接收方第一次收到私聊消息,自动弹出私聊窗口
if (!strs[1].equals(nickName)) {
FirstSecret = false;
jTextArea.append(strs[1] + "说:" + strs[3] + "\n");
jta.append("系统提示:" + strs[1] + "私信了你" + "\n");
handleSec(strs[1]);
} else {
jTextArea.append("我说:" + strs[3] + "\n");
}
}
} catch (Exception ex) {//如果服务器端出现问题,则客户端强制下线
JOptionPane.showMessageDialog(this, "您已被系统请出聊天室!");
System.exit(0);
}
}
}
```
## 第四章 源代码清单
Server.java
```java
package server;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
class Server extends JFrame implements Runnable, ListSelectionListener, ActionListener {
private ServerSocket ss = null;
private ArrayList<ChatThread> users = new ArrayList<ChatThread>(); //容量能够动态增长的数组
DefaultListModel<String> dl = new DefaultListModel<String>();
public JList<String> userList = new JList<String>(dl);//显示对象列表并且允许用户选择一个或多个项的组件。单独的模型 ListModel 维护列表的内容。
//群发消息输入栏
private JTextField jtf = new JTextField();
public Server() throws Exception {
this.setTitle("server");
this.add(userList, "North");//放在北面
JPanel jpl = new JPanel();
this.add(jpl, "South");
//仅将群发消息输入栏设为一栏
jtf.setColumns(2);
jpl.setLayout(new BorderLayout());
jpl.add(jtf, BorderLayout.NORTH);
JButton jbt = new JButton("踢人");
jpl.add(jbt, BorderLayout.WEST);//踢出聊天室
JButton jbt1 = new JButton("群发");
jpl.add(jbt1, BorderLayout.EAST);//群发消息
//实现群发
jbt1.addActionListener(this);
//实现踢人
jbt.addActionListener(this);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLocation(400, 100);
this.setSize(300, 400);
this.setVisible(true);
this.setAlwaysOnTop(true);
ss = new ServerSocket(8888);
new Thread(this).start();//监听用户端的加入
}
@Override
public void run() {
while (true) {
try {
Socket s = ss.accept();
ChatThread ct = new ChatThread(s); //为该客户开一个线程
users.add(ct); //将每个线程加入到users
//发送JList里的用户登陆信息,为了防止后面登陆的用户无法更新有前面用户的好友列表
ListModel<String> model = userList.getModel();//获取JList的数据内容
for (int i = 0; i < model.getSize(); i++) {
ct.ps.println("USERS#" + model.getElementAt(i));
}
ct.start();
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(this, "服务器异常!");
System.exit(0);
}
}
}
神仙别闹
- 粉丝: 4153
- 资源: 7485
最新资源
- 基于VS2017嵌套Qt插件开发的一款桌面应用程序,程序整体架构采用插件框架,各摸块通过插件管理器与主系统进行通讯,主系统主要功能包含xmpp、Mqtt即时通讯
- 基于乐鑫idf框架,研究出超稳定、掉线重连、解决内存泄露问题的Mqtt框架详细文档+全部资料.zip
- 基于ZigBee+ESP32+MQTT+EMQX+TomCat+Servlet接口+MySQL+安卓app的物联网课设详细文档+全部资料.zip
- 基于WPF的桌面应用,实现了MQTT通信,三次样条插值,用来控制机器人详细文档+全部资料.zip
- 基于树莓派、esp8266硬件模块 通过Python、Django、lua、mqtt消息队列协议、构建web远程控制平台:可控制小车移动、可视频实时查看详细文档
- 基于事件机制的多模块框架,支持动态库,grpc,websocket,mqtt等多种与后端通信组合方式. 模块动态替换,部分加载或者升级.详细文档+全部资料.zip
- 基于正点原子STM32F4开发板和阿里云物联网平台的MQTT项目详细文档+全部资料.zip
- 基于支持泛化协议接入的边缘网关框架, 以插件化的形式融合了 Modbus、Bacnet、HTTP、MQTT 等主流协议,同时也支持基于TCP的各类私有化协议对接详细文档+全部资料.zip
- 实训项目,计算机二级java刷题系统
- pajek 103369.rar:出色的大型网络分析软件,擅长处理复杂网络结构数据
- GooSeeker 125979:功能丰富的网络数据采集与分析工具
- 使用Matlab创建一个简单的类.pdf
- CiteSpace - 6.2.6.msi:知名的科学知识图谱绘制软件
- 关于web项目应用开发的心得和开发技巧以及关于如何配置开发环境、如何进行数据缓存管理、postman测试接口的使用教程、前后端
- 国开-网络安全技术-实验四 恶意代码攻防实验.doc
- 国开-网络安全技术-实验二 Wireshark安装和使用.doc
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈