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

本文为大家分享了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:SocketValue:用户名 public final static Map socketsMaps = Collections.synchronizedMap(new HashMap()); public static void main(String[] args) {// TODO Auto-generated method stubtry {// 创建服务端套接字ServerSocket serverSocket = new ServerSocket(9999); System.out.println("------服务端暴露-------"); while (true) {// 监听客户端套接字,若有客户端连接,则代码不会往下执行,否则会堵塞在此处。Socket socket = serverSocket.accept(); // 开启线程,用于读取客户端发送的信息,并转发给每一个客户端new ThreadServer(socket).start(); }} catch (Exception e) {// TODO: handle exceptione.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 = https://www.it610.com/article/dataInputStream.readUTF(); if(data.startsWith("①②③④")&&data.endsWith("①②③④")){//发送过来的是用户名//将Socket以及用户名字都存放在Map集合中ServerChat.socketsMaps.put(socket, data.replace("①②③④","")); //获取所有的key(Socket),将所有用户的名字发送至客户端Set sockets = ServerChat.socketsMaps.keySet(); //获取所有的用户的名字,将这些名字拼装成一个字符串Collection 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 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 blocke.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 userListModel = new DefaultListModel<>(); private JList 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, "请输入您的用户名:"); // 把用户输入的用户名,赋给curUsercurUser = 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() {@Overridepublic 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 exceptione.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 exceptione.printStackTrace(); }}public DefaultListModel 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+"\t\n"); }}} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace(); }}}

3.实验截图
先开启服务端
Java多线程实现多人聊天室功能
文章图片

再开启客户端
Java多线程实现多人聊天室功能
文章图片

聊天过程
Java多线程实现多人聊天室功能
文章图片

【Java多线程实现多人聊天室功能】以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    推荐阅读