Java的的的的聊天室
源代码下载
首先我们来看看程序界面,丑到爆!!!,勉强能用就行啦
第一个:登录界面
第二个:用户界面
第三个:服务器界面
好了上面三个界面是程序的主界面,下面我们先讲讲如何使用源代码
使用条件:一数据库,我这里用的MySQL的的的数据库,如果使用其他数据库比如甲骨文
需要去cn.scau.util包的DBproperties配置文件中重新配置数据库参数
我们来看看原来的配置
比如username password url使用jdbc的朋友应该更懂,还有自己导入对应数据库的驱动包
二。数据库中所用到的表
首先看看表结构
说明一下各个字段的类型:
字段类型
register_time:TIMESTAMP
用户名:VARCHAR
密码:VARCHAR
昵称:VARCHAR
USER_ID:INT
所以要建立chatuser表先,再在配置文件DBproperties中配置数据库
三:我是用的netbeans的编写的,如果用的NetBeans的导入项目的话,再满足上面两个条件就可以运行啦
好了讲完使用,我们来说说程序的整体思路
首先看看客户端和服务端的流程图
什么意思呢?我来解释一下
首先,图中有三个类,一个方法。三个类分别是:ServerThread,ClientThread,MessageThread
一个方法: conServer
其中:ServerThread,ClientThread属于服务器的类,而MessageThread,conServer属于客户端
最后:依照流程图,首先客户端的conServer,发起向服务端的连接,服务端的ServerThread是提前开
启的,ServerThread线程接受客户端的连接,新建一个ClientThread线程为这个新连接的客户端服务
这里的服务是接受这个客户端的信息,和向这个客户端发送信息,同时呢,在遥远的青青草原
上的客户端也会开启一个线程,它就是MessageThread,专门用来接收来自服务端对应的 ClientThread线程发来的消息。
为什么这样呢,因为这样服务端每次接收到新的客户端的连接,就会为它分配一个ClientThread线程
我们在服务端维护这个ClientThread线程列表,就可以区分每个客户端了,由于每个客户端在服务器
都有一个对应的ClientThread线程,所以客户端发送的信息也不会乱。
最后我们来看看流程图中的代码,也是这个聊天室的核心
//服务器线程,用来接收用户登录
class ServerThread extends Thread {
private boolean ifopen;
private ServerSocket serverSocket;
public ServerThread() {
this.ifopen = true;
}
@Override
public void run() {
try {
serverSocket = new ServerSocket(port);
JOptionPane.showMessageDialog(su.getJframe(), "服务器成功启动");
while (ifopen) {
Socket clnSocket = serverSocket.accept();//阻塞接收客户端的连接
if (userList.size() == max) {
su.getShowMessage().append("有客户端尝试连接服务端,但在线人数已达上限" + ServerUtil.getTime() + "\r\n");
clnSocket.close();
continue;
}
//每个客户端都有对应的线程处理
ClientThread client = new ClientThread(clnSocket);
su.getListModel().addElement(client.user.getName());//用户列表更新
userList.put(client.getUser().getName(), client);
client.start();
}
} catch (BindException be) {
JOptionPane.showMessageDialog(su.getJframe(), "端口已经被占用,请重新启动!", "error", JOptionPane.ERROR_MESSAGE);
return;
} catch (Exception ex) {
ex.printStackTrace();
}
}
public ServerSocket getServerSocket() {
return serverSocket;
}
public void setIfopen(boolean ifopen) {
this.ifopen = ifopen;
}
}
//<!----------------------------------ClientThread类分割线---------------------------------------------------------->
/*
每个连接到服务器的Client,都有一个线程来单独处理,接受消息
*/
class ClientThread extends Thread {
private ObjectOutputStream oos;
private ObjectInputStream ois;
private Socket socket;
private User user;
private boolean ifopen;
public void PrivateSend(String message) {
}
// 每个客户端对应一个客户端线程处理
public ClientThread(Socket socket) {
this.ifopen = true;
this.socket = socket;
try {
ois = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
oos = new ObjectOutputStream(socket.getOutputStream());
Object obj = ois.readObject();//读取用户信息包------------------------------------读取包
DataBag db = (DataBag) obj;//取得数据包,第一个数据包存储了用户的信息
this.user = db.getUser();//首先得到登录用户的信息
//通知其他客户端,新用户上线
BagTarget bt = new BagTarget();
bt.setOption(GROUP_CHAT);
bt.setGroupOption(USER_ADD);
db.setBt(bt);//----------------------3目的地数据
GroupSend(db);//--------------------------------------------向其他在线用户群发有新的用户登录包
//向刚登录的用户发送当前在线的用户列表
if (userList.size() > 0) {
DataBag dblist = new DataBag();
HashMap<String, User> onlineUser = new HashMap<String, User>();
Iterator iter = userList.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
String key = (String) entry.getKey();
ClientThread val = (ClientThread) entry.getValue();
onlineUser.put(key, val.getUser());
}
dblist.setUserlist(onlineUser);//-----------------------4在线的用户
BagTarget btList = new BagTarget();
btList.setOption(GROUP_CHAT);
btList.setGroupOption(USER_LIST);
dblist.setBt(btList);//曾经的bug出错点-------------------------------------bug bug bug------------------------------>
oos.writeObject(dblist);
oos.flush();
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}
//<----------------------------------------消息接收类---------------------------------------------->
//全天候接受信息
class MessageThread extends Thread {
private boolean ifopen;
public MessageThread() {
this.ifopen = true;
}
@Override
public void run() {
try {
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
//先发送自身的信息给服务器
DataBag db = new DataBag();
db.setUser(user);
oos.writeObject(db);
oos.flush();
while (ifopen) {
Object obj = ois.readObject();
db = (DataBag) obj;
int option = db.getBt().getOption();//判断是私聊还是群聊
switch (option) {
case GROUP_CHAT:
GroupChat(db);
break;
case PRIVATE_CHAT:
PrivateRecv(db);
break;
default:
}
}
} catch (Exception ex) {
System.out.println(ex.getMessage());
ex.printStackTrace();
}
}
各位看官有问题的话请评论留言,我有空就过来回答