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: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();   }  }}

3.实验截图

先开启服务端

再开启客户端

聊天过程

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

也不要说曾经失去,失去的不是永远失去,得到的不是永远拥有,

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

相关文章:

你感兴趣的文章:

标签云: