java socket聊天室 swing做界面 Tcp为通讯协议 支持私聊 群聊 发文件
来源:互联网 发布:mac版flash 官方下载 编辑:程序博客网 时间:2024/05/14 05:39
java聊天室
首先我们来看看程序界面,丑到爆!!!,勉强能用就行啦
第一个:登录界面
第二个:用户界面
第三个:服务器界面
好了上面三个界面是程序的主界面,下面我们先讲讲如何使用源代码
使用条件: 一。 数据库,我这里用mysql数据库,如果使用其他数据库比如oracle
需要去cn.scau.util包的DBproperties配置文件中重新配置数据库参数
我们来看看原来的配置
比如username password url使用jdbc的朋友应该更懂,还有自己导入对应数据库的驱动包
二。数据库中所用到的表
首先看看表结构
说明一下各个字段的类型:
字段 类型
register_time : TIMESTAMP
username : VARCHAR
password : VARCHAR
nickname : 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; } } /* 每个连接到服务器的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(); HashMaponlineUser = new HashMap (); 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(); } }// 重写run方法,用来循环接受消息 @Override public void run() { while (this.ifopen) { try { Object obj = ois.readObject(); DataBag db = (DataBag) obj; int option = db.getBt().getOption();//知道数据包要干嘛,私聊还是群聊- 0是群聊,1是私聊 switch (option) { case GROUP_CHAT: GroupChat(db); break; case PRIVATE_CHAT: PrivateChat(db); break; default: } } catch (IOException ex) { ex.printStackTrace(); } catch (ClassNotFoundException ex) { ex.printStackTrace(); } } } synchronized public ObjectOutputStream getOos() { return oos; } public User getUser() { return user; } public void setIfopen(boolean ifopen) { this.ifopen = ifopen; } } // 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(); } } public void setIfopen(boolean ifopen) { this.ifopen = ifopen; } } public void conServer(User user) { String name = null; String ip = null; int port = 0; try { name = user.getName(); ip = user.getTargetIp(); port = user.getPort(); conCheck(name, ip, port);//throw 检查中的异常 this.socket = new Socket(ip, port);//生成客户端socket //String userList = bfread.readLine(); //接受消息的线程启动 mt = new MessageThread(); mt.start(); /* if (socket.isClosed() == false) { JOptionPane.showMessageDialog(cu.getJframe(), "连接成功"); }*/ this.iflogin = true; } catch (IOException ex) { this.iflogin = false; cu.getShowMessage().append("连接服务ip:" + ip + "端口:" + port + "的服务器失败!" + ClientUtil.getTime() + "\r\n"); ex.printStackTrace(); } catch (Exception ex) { this.iflogin = false; JOptionPane.showMessageDialog(cu.getJframe(), ex.getMessage()); } } // //服务器线程,用来接收用户登录 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; } }
各位看官有问题的话请评论留言,我有空就过来回答
源代码在我的资源中下载,不用积分
- java socket聊天室 swing做界面 Tcp为通讯协议 支持私聊 群聊 发文件
- Java Socket实现多人聊天室---swing做UI
- Java Socket实现多人聊天室---swing做UI
- Java Socket实现多人聊天室---swing做UI
- Java Socket实现多人聊天室---swing做UI
- JAVA 基于TCP协议编写的Socket聊天室程序
- java Socket TCP通讯
- Socket实现聊天发文件
- VC中的socket通讯例程(TCP协议)
- 基于SOCKET机制的TCP协议通讯
- 基于SOCKET机制的TCP协议通讯
- TCP通讯socket自定义协议的实现
- java基于socket tcp的简单聊天室
- socket编程 通讯协议tcp,数据承载协议http
- TCP/IP协议、HTTP协议、SOCKET通讯详解
- 基于java Swing测TCP Socket 实例
- java swing聊天室代码
- TCP/IP协议(Socket)做服务器,HTTP协议做客户端
- xhr请求方式
- 哈夫曼树--贪心算法
- 罕见影像:140 多年前的中国
- Streams filter 例子
- WPF使用其他dll里的样式
- java socket聊天室 swing做界面 Tcp为通讯协议 支持私聊 群聊 发文件
- 统计英文文件中单词数和各单词出现的频率(次数)
- 排序之快排
- 2017年第十届河南省ACM省赛 B题情报传递
- attribute: attribute is not a string value报错解决:Android中对比string程序
- Makefile经典教程(掌握这些足够)
- 【数据结构】【C++STL】FIFO队列&优先队列
- Linux虚拟内存管理
- Spring MVC(1)-运行原理