基于Java的群聊系统

Roselani ·
更新时间:2024-09-20
· 674 次阅读

最近研究生复试,特定将自己大二写的程序拿出来,因为实在没什么项目经验。当时也是在网上参考了些信息,不过自己也忘记是哪个博主的了,特此感谢之前的博主。接下来将这个程序的思路与源码分享给大家。里面有多多不足还请包涵。
完整的程序代码我将放在我的GitHub上,供大家下载。
GitHub完整源码

首先是服务器部分:
首先写一个服务器类继承JFrame用于可视化窗口。在类里面写以获得消息的函数getMessage。在getMessage里面启动信息传输线程。创建套接字不断接受来客户端的套接字。将新增加的客户端增加到列表中。代表如下:

public void getmessages() { //启动普通信息传输器 new PrintOutThread(); try { ServerSocket server=null; server=new ServerSocket(2559); System.out.println("普通消息传输服务器"+2559); String messages; int i=0; Socket s; while(true) { s=server.accept(); //receiveFile(s); thread_list.add(new ServerThread(s,i)); i++; } } catch(Exception e) { System.err.println("发生异常:"+e); e.printStackTrace(); } }

客户端列表的定义如下:

private static List thread_list = new ArrayList();

接下来我们解析ServerThread类。
1,在类中定义int id,Socket socket两个变量。
2,为了接收和发出消息定义一个输入流一个输出流对象
private ObjectOutputStream m_output;//输出流
private ObjectInputStream m_input;//输入流
接下来则在创建构造函数包含套接字socket,id两个参数。
id是用来标准每个客户端的。在构造函数中获取获取套接字的输入输出流。并且启动线程。代码如下:

public ServerThread(Socket s,int i) { client = s; id=i; try { m_input=new ObjectInputStream(s.getInputStream()); m_output=new ObjectOutputStream(s.getOutputStream()); start(); }catch(Exception e) { e.printStackTrace(); } }

接着我们查看run()函数里面的动作。
即我们不断获取来自客户端的消息,直到接收到客户端退出的消息。在接收消息时这里是将接收的消息全部放入消息队列当中,因为我们实现的是群聊。从而要实现一个客户端发完消息,服务器要将消息转发给除自己外,其他所有客户端。
代码如下:

public void run() { // TODO Auto-generated method stub try { String messages; offLine=true; while(offLine) { messages=m_input.readObject().toString(); if(messages.equals("!exit!")) offLine=false; message_list.add(new Message(id,messages)); isPrint=true; } m_output.flush(); m_output.close(); m_input.close(); client.close(); }catch(Exception e) { e.printStackTrace(); } }

接下来我们就是讲下Message类,其实这个类主要是就是为了将消息绑上ID等等有发送线程发送就知道是谁的消息了。

public class Message { private int ID; private String msg; public Message(int n,String m) { ID=n; msg=m; } public int getName() { return ID; } public String getMsg() { return msg; } }

就下来就是服务器的最后一部分了。就是要开始发送消息了。在之前我们就已经启动了消息进程。直接在消息进程的run函数发送数据。首先对消息队列有个判断,若消息队列为空,则阻塞消息队列一段时间,目标为了将cpu让给其他线程。对与这一部分。大家可以去看下操作系统,cpu调度这一块。会给更加便于大家理解。接下来接收将消息队列取出消息。并且在服务器端队列取出各个来客户端的线程。判断若消息不是来自该客户端,若不是,则该服务器线程端发送给数据给该客户端。若是则不发送。代码如下:

public void run() { while (true) { //如果消息队列没有消息则暂停当前线程,把cpu片段让出给其他线程,提高性能 if (!isPrint) { try { Thread.sleep(500); sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } continue; } // 将缓存在队列中的消息按顺序发送到各客户端,并从队列中清除。 Message msg = (Message)message_list.getFirst(); // 对所有的用户的线程遍历,如果不是自己发的消息就广播给其他人 for (int i = 0; i 0 ? true : false; }

最后一块大家看代码其实会更加清楚。这就是服务器的部分了。理解好服务器很重要。客户端相对来说就很好理解了。客户端我也上传到GitHub了,大家只需要上去下载就行了。过程就不说了。大家自己看看。

粤海门 原创文章 6获赞 4访问量 1135 关注 私信 展开阅读全文
作者:粤海门



系统 java的 JAVA

需要 登录 后方可回复, 如果你还没有账号请 注册新账号