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

网友投稿 229 2023-01-03

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 socketsMaps = Collections.synchronizedMap(new HashMap());

ezxKRRrbQTpublic 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 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()+"①②③④");

dataOutezxKRRrbQTputStream.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 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 diezxKRRrbQTsplayTa = 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, "请输入您的用户名:");

// 把用户输入的用户名,赋给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 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.实验截图

先开启服务端

再开启客户端

聊天过程

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:初次体验MyBatis的注意事项
下一篇:天马快递物流查询单号(天马官网快递查询)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~