您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
小编给大家分享一下Java多线程如何实现多人聊天室功能,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!
编写一个 Java 应用程序,实现图形界面多人聊天室(多线程实现),要求聊天室窗口标题是 “欢迎使用 XXX 聊天室应用”,其中 XXX 是自己的班级姓名学号,如“软件 171 张三 1234”。
服务端程序代码:
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+"\t\n"); } } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
先开启服务端
再开启客户端
聊天过程
以上是“Java多线程如何实现多人聊天室功能”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。