一对多聊天室

多人聊天包

由于要先创建服务面板,接收客户端连接的信息,此代码使用顺序为先启动服务端,在启动客户端,服务端不用关,不然会报错。多运行几次客户端,实现单人聊天

创建服务面板

package yiduiduo;import java.awt.BorderLayout;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;public class Ltmb extends JFrame {private JTextArea ta_info;private ServerSocket server; // 声明ServerSocket对象private Socket socket; // 声明Socket对象socketprivate Hashtable<String, Socket> map = new Hashtable<String, Socket>();// 用于存储连接到服务器的用户和客户端套接字对象public void createSocket() {try {server = new ServerSocket(1978);while (true) {ta_info.append("等待新客户连接......\n");socket = server.accept();// 创建套接字对象ta_info.append("客户端连接成功。" + socket + "\n");new ServerThread(socket).start();// 创建并启动线程对象}} catch (IOException e) {e.printStackTrace();}}class ServerThread extends Thread {Socket socket;public ServerThread(Socket socket) {this.socket = socket;}public void run() {try {BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));// 创建输入流对象while (true) {String info = in.readLine();// 读取信息String key = "";if (info.startsWith("用户:")) {// 添加登录用户到客户端列表key = info.substring(3, info.length());// 获得用户名并作为键使用map.put(key, socket);// 添加键值对Set<String> set = map.keySet();// 获得集合中所有键的Set视图Iterator<String> keyIt = set.iterator();// 获得所有键的迭代器while (keyIt.hasNext()) {String receiveKey = keyIt.next();// 获得表示接收信息的键Socket s = map.get(receiveKey);// 获得与该键对应的套接字对象PrintWriter out = new PrintWriter(s.getOutputStream(), true);// 创建输出流对象Iterator<String> keyIt1 = set.iterator();// 获得所有键的迭代器while (keyIt1.hasNext()) {String receiveKey1 = keyIt1.next();// 获得键,用于向客户端添加用户列表out.println(receiveKey1);// 发送信息out.flush();// 刷新输出缓冲区}}} else {// 转发接收的消息key = info.substring(info.indexOf(":发送给:") + 5, info.indexOf(":的信息是:"));// 获得接收方的key值,即接收方的用户名String sendUser = info.substring(0, info.indexOf(":发送给:"));// 获得发送方的key值,即发送方的用户名Set<String> set = map.keySet();// 获得集合中所有键的Set视图Iterator<String> keyIt = set.iterator();// 获得所有键的迭代器while (keyIt.hasNext()) {String receiveKey = keyIt.next();// 获得表示接收信息的键if (key.equals(receiveKey)&& !sendUser.equals(receiveKey)) {// 如果是发送方,但不是用户本身Socket s = map.get(receiveKey);// 获得与该键对应的套接字对象PrintWriter out = new PrintWriter(s.getOutputStream(), true);// 创建输出流对象out.println("MSG:"+info);// 发送信息out.flush();// 刷新输出缓冲区}}}}} catch (IOException e) {ta_info.append(socket + "已经退出。\n");}}}public static void main(String args[]) {Ltmb frame = new Ltmb();frame.setVisible(true);frame.createSocket();}public Ltmb() {super();setTitle("多个用户聊天");setBounds(100, 100, 385, 266);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);final JScrollPane scrollPane = new JScrollPane();getContentPane().add(scrollPane, BorderLayout.CENTER);ta_info = new JTextArea();scrollPane.setViewportView(ta_info);}
}

创建客户面板

package yiduiduo;import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;public class Kehuduan extends JFrame {private JTextArea ta_info;private JTextField tf_send;PrintWriter out;// 声明输出流对象/*** Launch the application* * @param args*/public static void main(String args[]) {EventQueue.invokeLater(new Runnable() {public void run() {try {Kehuduan frame = new Kehuduan();frame.setVisible(true);frame.createClientSocket();} catch (Exception e) {e.printStackTrace();}}});}public void createClientSocket() {try {Socket socket = new Socket("127.0.0.1", 1978);// 连接本地1978端口out = new PrintWriter(socket.getOutputStream(), true);// 创建输出流对象new ClientThread(socket).start();// 创建并启动线程对象} catch (UnknownHostException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}class ClientThread extends Thread {Socket socket;public ClientThread(Socket socket) {this.socket = socket;}public void run() {try {BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));// 创建输入流对象while (true) {String info = in.readLine();// 读取信息ta_info.append(info + "\n");// 在文本域中显示信息if (info.equals("88")) {break;// 结束线程}}} catch (IOException e) {e.printStackTrace();}}}private void send() {String info = tf_send.getText();// 获得输入的信息if (info.equals("")) {return;// 如果没输入信息则返回,即不发送}if (info.equals("88")) {System.exit(0);// 如果没输入信息是88,则退出}out.println(info);// 发送信息out.flush();// 刷新输出缓冲区tf_send.setText(null);// 清空文本框}public Kehuduan() {  //创建面板super();setTitle("客户互相聊天");setBounds(100, 100, 385, 266);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);final JPanel panel = new JPanel();getContentPane().add(panel, BorderLayout.SOUTH);final JLabel label = new JLabel();label.setText("输入聊天内容:");panel.add(label);tf_send = new JTextField();tf_send.addActionListener(new ActionListener() {public void actionPerformed(final ActionEvent e) {send();}});tf_send.setPreferredSize(new Dimension(180, 25));panel.add(tf_send);final JButton button = new JButton();button.addActionListener(new ActionListener() {public void actionPerformed(final ActionEvent e) {send();}});button.setText("发  送");panel.add(button);final JScrollPane scrollPane = new JScrollPane();getContentPane().add(scrollPane, BorderLayout.CENTER);ta_info = new JTextArea();scrollPane.setViewportView(ta_info);}}

结果如下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/207805.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【头歌系统数据库实验】实验7 SQL的复杂多表查询-1

目录 第1关&#xff1a;求各颜色零件的平均重量 第2关&#xff1a;求北京和天津供应商的总个数 第3关&#xff1a;求各供应商供应的零件总数 第4关&#xff1a;求各供应商供应给各工程的零件总数 第5关&#xff1a;求重量大于所有零件平均重量的零件名称 第6关&#xff1…

初识人工智能,一文读懂人工智能概论(1)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

Python Django-allauth: 构建全面的用户身份验证系统

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com Django-allauth是一个功能强大的Django插件&#xff0c;旨在简化和定制Web应用程序中的用户身份验证和管理。本文将深入介绍Django-allauth的核心功能、基本用法以及实际应用场景&#xff0c;通过丰富的示例代码…

AWTK 串口屏开发(1) - Hello World

1. 功能 这个例子很简单&#xff0c;制作一个调节温度的界面。在这里例子中&#xff0c;模型&#xff08;也就是数据&#xff09;里只有一个温度变量&#xff1a; 变量名数据类型功能说明温度整数温度。范围 (0-100) 摄氏度 2. 创建项目 从模板创建项目&#xff0c;将 hmi/…

网络运维与网络安全 学习笔记2023.12.4

网络运维与网络安全 学习笔记 第三十四天 今日目标 访问存储设备、配置yum源、使用yum管理软件 LAMP部署及测试、systemctl系统控制、SELinux-Firewall防护 访问存储设备 挂载/卸载设备 什么是挂载? 挂载&#xff0c;装载 将光盘/U盘/分区/网络存储等设备装到某个Linux目…

pycharm debug的时候变量显示不出来,一直Collecting data...问题解决

问题描述&#xff1a; 如图所示&#xff1a;一直加载不出来变量&#xff0c;显示Collecting data 解决办法&#xff1a; 在setting中给下图中的选项打勾 这下就可以了。 应该是调试时候有线程冲突&#xff0c;具体我也不太懂。

mysql服务日志打印,时区不对的问题

查资料发现 原来日志的时区和服务器的时区不是一个参数控制的 log_timestamps 单独控制日志的时区 show global variables like log_timestamps;看到默认的是UTC&#xff0c;只需要修改为和系统一致就行 #数据库中直接修改 set global log_timestampsSYSTEM;#配置文件my.cn…

springboot086靓车汽车销售网站

springboot086靓车汽车销售网站 成品项目已经更新&#xff01;同学们可以打开链接查看&#xff01;需要定做的及时联系我&#xff01;专业团队定做&#xff01;全程包售后&#xff01; 2000套项目视频链接&#xff1a;https://pan.baidu.com/s/1N4L3zMQ9nNm8nvEVfIR2pg?pwd…

APP测试基本流程及测试点总结

APP测试基本流程及测试点总结 1 测试流程 1.1 流程图 1.2 测试周期 测试周期可按项目的开发周期来确定测试时间&#xff0c;一般测试时间为两三周&#xff08;即15个工作日&#xff09;&#xff0c;根据项目情况以及版本质量可适当缩短或延长测试时间。 1.3 测试资源 测试任务…

VQVAE

68、VQVAE预训练模型的论文原理及PyTorch代码逐行讲解_哔哩哔哩_bilibili本期视频主要讲解大规模无监督预训练模型之VQVAE的论文原理以及PyTorch代码逐行讲解&#xff0c;希望对大家理解VQVAE以及图像生成有帮助。, 视频播放量 9920、弹幕量 80、点赞数 485、投硬币枚数 322、收…

Linux:dockerfile编写搭建tomcat练习(9)

我使用的httpyum仓库 本地使用了5个文件&#xff0c;tomcat使用的官网解压直接用的包】 Dockerfile 主配置文件 基于centos基础镜像 jdk1.8.0_91 java环境 run.sh 启动脚本 centos.repo 仓库文件 tomcat 源码包 vim Dockerfile写入FROM centos MAINTAINER ta…

一个 postman实现参数化让我丢掉了一份20k的offer

什么时候会用到参数化 比如&#xff1a;一个模块要用多组不同数据进行测试 验证业务的正确性 Login模块&#xff1a;正确的用户名&#xff0c;密码 成功&#xff1b;错误的用户名&#xff0c;正确的密码 失败 postman实现参数化 在实际的接口测试中&#xff0c;部分参数…

Ubuntu22.04安装和卸载软件的命令行

一、安装 sudo apt install xxx 二、卸载 sudo apt remove xxx 三、卸载依赖包(可选) 第二步软件卸载之后&#xff0c;有一些依赖包没有被卸载。可以使用sudo apt autoremove xxx来卸载。如果不卸载应该也没什么影响

Andorid sudio 换行方法

1.遇到的问题&#xff0c;二维码内容要换行 String text "成绩&#xff1a;1000 \n姓名&#xff1a;张三 \n姓名&#xff1a;张三 \n姓名&#xff1a;张三 \n姓名&#xff1a;张三 \n姓名&#xff1a;张三 \n姓名&#xff1a;张三 \n姓名&#xff1a;张三 \n姓名&#xff…

阿里云服务器2核8G/4核16G/8核32G配置选择经济型、通用算力型、通用型哪个好?

2核8G/4核16G/8核32G配置的阿里云服务器在阿里云活动中目前有经济型e、通用算力型u1、通用型c7和通用型g8y四种实例可选&#xff0c;虽然配置相同&#xff0c;但是这些实例规格之间的价格差别是很大的&#xff0c;以2核8G配置为例&#xff0c;活动价格最便宜的经济型e实例2核8G…

2023亚太五岳杯量子计算挑战赛数学建模思路代码模型论文

2023五岳杯数学建模思路&#xff1a;比赛开始后第一时间更新&#xff0c;获取见文末名片 今年&#xff0c;APMCM亚太地区大学生数学建模竞赛组委会正式和玻色量子、中国移动云能力中心等多家单位达成合作。 开展APMCM校企合作高校巡回学术讲座活动&#xff0c;为企业、高校搭…

Python并发-线程和进程

一、线程和进程对应的问题 **1.进程&#xff1a;**CPU密集型也叫计算密集型&#xff0c;指的是系统的硬盘、内存性能相对CPU要好很多&#xff0c;此时&#xff0c;系统运作大部分的状况是CPU Loading 100%&#xff0c;CPU要读/写I/O(硬盘/内存)&#xff0c;I/O在很短的时间就可…

C语言之函数

目录 main函数和库函数 什么是函数 函数定义 函数头&#xff08;function header&#xff09; 1.返回类型&#xff08;return type&#xff09; 2.函数名&#xff08;function name&#xff09; 3.形参声明&#xff08;parameter type list&#xff09; 函数体&#xff…

通过静态HTTP实现负载均衡

在当今的互联网环境中&#xff0c;随着用户数量的不断增加和业务需求的不断扩大&#xff0c;单台服务器往往无法承受所有的访问压力。为了确保网站的可用性和性能&#xff0c;负载均衡成为了一种常见的解决方案。本文将探讨如何通过静态HTTP实现负载均衡&#xff0c;以提升网站…