您的位置:首页技术文章
文章详情页

Java多线程实现多人聊天室功能

【字号: 日期:2022-08-09 17:53:08浏览:3作者:猪猪

本文为大家分享了Java多线程实现多人聊天室功能的具体代码,供大家参考,具体内容如下

1.实验目的:

编写一个 Java 应用程序,实现图形界面多人聊天室(多线程实现),要求聊天室窗口标题是 “欢迎使用 XXX 聊天室应用”,其中 XXX 是自己的班级姓名学号,如“软件 171 张三 1234”。

2.实验代码:

服务端程序代码:

ServerChar.java

package works;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.Collection;import java.util.Collections;import java.util.HashMap;import java.util.Map;import java.util.Set;public class ServerChat { //定义Map集合用于存储用户的Socket以及用户的名字 key:Socket Value:用户名 public final static Map<Socket,String> socketsMaps = Collections.synchronizedMap(new HashMap<Socket,String>()); public static void main(String[] args) { // TODO Auto-generated method stub try { // 创建服务端套接字 ServerSocket serverSocket = new ServerSocket(9999); System.out.println('------服务端暴露-------'); while (true) { // 监听客户端套接字,若有客户端连接,则代码不会往下执行,否则会堵塞在此处。 Socket socket = serverSocket.accept(); // 开启线程,用于读取客户端发送的信息,并转发给每一个客户端 new ThreadServer(socket).start(); } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } }}class ThreadServer extends Thread { private Socket socket; ThreadServer(){}; ThreadServer(Socket socket) { this.socket = socket; } @Override public void run() { try { while(true) { DataInputStream dataInputStream = new DataInputStream(socket.getInputStream()); String data = dataInputStream.readUTF();if(data.startsWith('①②③④')&&data.endsWith('①②③④')) { //发送过来的是用户名 //将Socket以及用户名字都存放在Map集合中 ServerChat.socketsMaps.put(socket, data.replace('①②③④','')); //获取所有的key(Socket),将所有用户的名字发送至客户端 Set<Socket> sockets = ServerChat.socketsMaps.keySet(); //获取所有的用户的名字,将这些名字拼装成一个字符串 Collection<String> names = ServerChat.socketsMaps.values(); StringBuffer sbf = new StringBuffer(); for(String userName :names) { sbf.append(userName).append(','); } System.out.println('sbf:'+sbf.toString()); for(Socket soc:sockets) { DataOutputStream dataOutputStream = new DataOutputStream(soc.getOutputStream()); dataOutputStream.writeUTF('①②③④'+sbf.toString()+'①②③④'); dataOutputStream.flush(); } } else{ //发送过来的是聊天信息 //获取所有的key(Socket),将所有用户的名字发送至客户端 Set<Socket> sockets = ServerChat.socketsMaps.keySet(); //?⒘奶煨畔⒐悴コ鋈 for(Socket soc:sockets) { DataOutputStream dataOutputStream = new DataOutputStream(soc.getOutputStream()); dataOutputStream.writeUTF('[ '+ServerChat.socketsMaps.get(socket)+' ]说:'+data); dataOutputStream.flush(); } } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}

客户端程序代码:

ClientChar.java

package works;import java.awt.BorderLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.Socket;import javax.swing.Box;import javax.swing.BoxLayout;import javax.swing.DefaultListModel;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JList;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;public class ClientChat { private JFrame mainWin = new JFrame('聊天窗口'); // 消息展示框 private JTextArea displayTa = new JTextArea(14, 40); // 在线用户名称展示框 private DefaultListModel<String> userListModel = new DefaultListModel<>(); private JList<String> userList = new JList<>(userListModel); // 消息发送框 private JTextArea inputTF = new JTextArea(4, 40); // 消息按钮 private JButton sendBn = new JButton('发送'); // 用户记录当前聊天用户名 private String curUser; public static void main(String[] args) { new ClientChat().init(); } private void init() { try { // 通过弹出对话框获取用户输入的用户名 String userName = JOptionPane.showInputDialog(mainWin, '请输入您的用户名:'); // 把用户输入的用户名,赋给curUser curUser = userName; mainWin.setTitle(curUser + '的聊天窗口'); // 创建套接字 Socket socket = new Socket('192.168.193.1', 9999); // 向服务器声明 DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()); //发送用户名到服务端 dataOutputStream.writeUTF('①②③④'+userName+'①②③④'); dataOutputStream.flush(); // 开启线程,用于读取服务器发送的信息 new ThreadClient(socket, this).start(); JPanel bottomPanel = new JPanel(); // 将消息框和按钮添加到窗口的底端 mainWin.add(bottomPanel, BorderLayout.SOUTH); bottomPanel.add(inputTF); bottomPanel.add(sendBn); ActionListener listener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // 获取用户发送的消息 String message = inputTF.getText(); sendSms(message,socket); } }; // 给发送消息按钮绑定点击事件监听器 sendBn.addActionListener(listener); JPanel centerPanel = new JPanel(); // 将展示消息区centerPanel添加到窗口的中间 mainWin.add(centerPanel); // 让展示消息区可以滚动 centerPanel.add(new JScrollPane(displayTa)); displayTa.setEditable(false); // 用户列表和是否私聊放到窗口的最右边 Box rightBox = new Box(BoxLayout.Y_AXIS); userList.setFixedCellWidth(60); userList.setVisibleRowCount(13); rightBox.add(new JLabel('用户列表:')); rightBox.add(new JScrollPane(userList)); centerPanel.add(rightBox); // 关闭窗口退出当前程序 mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainWin.pack(); // swing加上这句就可以拥有关闭窗口的功能 mainWin.setVisible(true); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } //点击发送后将消息发送到服务器 protected void sendSms(String sms, Socket socket) { try { //发送聊天消息到服务端 DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream()); dataOutputStream.writeUTF(sms); dataOutputStream.flush(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } public DefaultListModel<String> getUserListModel() { return userListModel; } public JTextArea getDisplayTa() { return displayTa; } public JTextArea getInputTF() { return inputTF; }}// 定义线程类,用来读取服务器发送的信息class ThreadClient extends Thread { private Socket socket; private ClientChat clientChat; ThreadClient() { } ThreadClient(Socket socket, ClientChat clientChat) { this.socket = socket; this.clientChat = clientChat; } @Override public void run() { try { while (true) { DataInputStream DataInputStream = new DataInputStream(socket.getInputStream()); String message = DataInputStream.readUTF(); if(message.startsWith('①②③④')&&message.endsWith('①②③④')) { //说明信息是用户名 String[] names = message.replace('①②③④','').split(','); // 将用户列表先清空 clientChat.getUserListModel().clear(); for (int i = 0; i < names.length; ++i) { clientChat.getUserListModel().addElement(names[i]); } } else { //说明是聊天信息,将聊天信息放在displayTa中 clientChat.getInputTF().setText(''); clientChat.getDisplayTa().append(message+'tn'); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}3.实验截图

先开启服务端

Java多线程实现多人聊天室功能

再开启客户端

Java多线程实现多人聊天室功能

聊天过程

Java多线程实现多人聊天室功能

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持好吧啦网。

标签: Java
相关文章: