java实现网络聊天

 网络聊天实现步骤(从功能谈论方法):

客户端:

1.登录面板:注册提醒用户注册格式,登录账号密码不为空,点击登录的时候需要连接服务器端,启动聊天面板。(监听用户点击登录,这时候连接服务器)

2.聊天面板:消息框接收服务器端发送的消息,发送消息框保存消息内容,点击发送按钮将发送消息框递给服务器端(需要创造一个线程不断监听服务器端发送回来的消息,并且显示在消息框)

服务器端:

1.服务器端需要循环监听客户端发送过来的连接

2.把循环接收到的多个客户端用集合储存起来

3.为每个客户端建立一个线程,用来接收他们发送的消息并且为其他客户端转送消息。

4.发送公告功能:聊天面板,发送公告面板,发送按钮(将发送面板的消息发送给各个客户端)。

客户端启动界面
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.Socket;public class Logon extends JFrame {public Logon() {this.setTitle("欢迎登录");this.setSize(400, 400);this.setLocationRelativeTo(null);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//标签JLabel jLabel = new JLabel("欢迎登录");jLabel.setFont(new Font("楷体", Font.BOLD, 20));//字体jLabel.setForeground(new Color(21, 12, 12));JPanel jPanel = new JPanel();jPanel.add(jLabel);//账号JPanel jPanel1 = new JPanel();JLabel jLabel1 = new JLabel("账号");JTextField jTextField1 = new JTextField(15);jPanel1.add(jLabel1);jPanel1.add(jTextField1);//密码JPanel jPanel2 = new JPanel();JLabel jLabel2 = new JLabel("密码");JTextField jTextField2 = new JTextField(15);jPanel2.add(jLabel2);jPanel2.add(jTextField2);//按钮//登录JButton jButton = new JButton("登录");jButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (jTextField1.getText().equals("") || jTextField2.getText().equals("")) {JOptionPane.showMessageDialog(null, "请输入");} else {try {Socket socket = new Socket("192.168.124.89", 9999);new ChatMap(jTextField1.getText(),socket);dispose();} catch (IOException ioException) {ioException.printStackTrace();JOptionPane.showMessageDialog(null, "没有连接至服务器,请稍后");}}}});//注册JButton jButton1 = new JButton("注册");jButton1.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (!jTextField1.getText().matches("\\w*") || !jTextField2.getText().matches("\\w*")) {JOptionPane.showMessageDialog(null, "只支持大小写字母及数字");}}});JPanel jPanel3 = new JPanel();jPanel3.add(jButton);jPanel3.add(jButton1);this.setLayout(new GridLayout(4, 1));this.add(jPanel);this.add(jPanel1);this.add(jPanel2);this.add(jPanel3);this.setVisible(true);//让窗口显示,放在代码的最后一行。}
}

客户端聊天界面
import javax.swing.*;
import java.awt.*;
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 java.text.SimpleDateFormat;
import java.util.Date;public class ChatMap extends JFrame {JTextArea jTextArea;public ChatMap(String account, Socket socket) throws IOException {//向服务器发送信息DataOutputStream dataOutputStream=new DataOutputStream(socket.getOutputStream());this.setTitle("欢迎来到"+account+"聊天室");this.setSize(400, 400);this.setLocationRelativeTo(null);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//创造面版JPanel jPanel = new JPanel(new BorderLayout());//聊天窗口jTextArea = new JTextArea(20, 15);jTextArea.setEnabled(false);jTextArea.setLineWrap(true);JScrollPane jScrollPane = new JScrollPane(jTextArea);jPanel.add(jScrollPane,BorderLayout.NORTH);//输入窗口JTextArea jTextArea1 = new JTextArea(1, 10);jTextArea.setLineWrap(true);JScrollPane jScrollPane1 = new JScrollPane(jTextArea1);jPanel.add(jScrollPane1,BorderLayout.CENTER);//按钮JButton jButton=new JButton("发送");jButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String message=jTextArea1.getText();if(message.length()==0)//为什么要依靠message长度判断{JOptionPane.showMessageDialog(null, "输入不能为空");return;}//不为空显示日期向服务器发送信息Date date=new Date();SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String str=sdf.format(date);String msg=account+":"+str+"\n";msg+=message;try {dataOutputStream.writeUTF(msg);//发送消息jTextArea1.setText("");//清空发送框} catch (IOException ioException) {ioException.printStackTrace();JOptionPane.showMessageDialog(null, "内容发送失败,请检查网络");}}});jPanel.add(jButton,BorderLayout.EAST);this.add(jPanel);this.setVisible(true);//让窗口显示,放在代码的最后一行。//面板创造完毕建立监听(服务器传入的消息)new BThread(socket,jTextArea).start();}//内部类监听服务器端class BThread extends Thread{DataInputStream dataInputStream;public BThread(Socket socket,JTextArea jTextArea) throws IOException {dataInputStream=new DataInputStream(socket.getInputStream());}@Overridepublic void run() {while(true)//循环条件:退出{try {String message=dataInputStream.readUTF();jTextArea.append(message+"\n");} catch (IOException e) {e.printStackTrace();System.out.println("服务器断开连接");break;//停止客户端线程}}}}}

 

启动客户端
public class Run {public static void main(String[] args) {new Logon();}
}
服务器端界面
import javax.swing.*;
import java.awt.*;
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.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;public class server extends JFrame {ArrayList<Socket> sockets=new ArrayList<>();Socket socket;JTextArea jTextArea;JTextArea  jTextArea1;JButton jButton;public server(){//设置窗口this.setTitle("服务器");this.setSize(400, 400);this.setLocationRelativeTo(null);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);JPanel jPanel=new JPanel(new BorderLayout());jTextArea=new JTextArea();jTextArea.setEnabled(false);//不可进行操作jTextArea.setLineWrap(true);JScrollPane jScrollPane=new JScrollPane(jTextArea);//发送JPanel jPanel1=new JPanel();jTextArea1=new JTextArea();jTextArea1.setEnabled(true);//可进行操作jTextArea1.setLineWrap(true);JScrollPane jScrollPane1=new JScrollPane(jTextArea1);jButton=new JButton("发送");jButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String massage=jTextArea1.getText();for (Socket s:sockets){DataOutputStream dOut= null;try {dOut = new DataOutputStream(s.getOutputStream());dOut.writeUTF("公告:"+massage);} catch (IOException ioException) {ioException.printStackTrace();JOptionPane.showMessageDialog(null, "发送失败");}}}});jPanel1.add(jScrollPane1);jPanel1.add(jButton);jPanel.add(jScrollPane);jPanel.add(jPanel1,BorderLayout.SOUTH);this.add(jPanel);this.setVisible(true);//启动服务器this.startServer();}public void startServer(){try {ServerSocket serverSocket=new ServerSocket(9999);while(true){socket= serverSocket.accept();//阻塞程序System.out.println("服务器启动成功");sockets.add(socket);System.out.println("有客户端连接上了,客户端连接数为:"+sockets.size());//为每一个连接到服务器的客户端开启一个线程new A(socket).start();}} catch (IOException e) {e.printStackTrace();System.out.println("启动服务器失败");}}//创造一个内部类监听各个客户端是否给服务器端发送消息class A extends Thread{DataInputStream dataInputStream;public A(Socket socket) throws IOException {dataInputStream=new DataInputStream(socket.getInputStream());}@Overridepublic void run() {while (true){//一直厮混换,监听客户端发送的消息try {String msg=dataInputStream.readUTF();jTextArea.append(msg+"\n");//向不同的客户端转发消息for(Socket s:sockets){DataOutputStream dOut=new DataOutputStream(s.getOutputStream());dOut.writeUTF(msg);}} catch (IOException e) {e.printStackTrace();System.out.println("一位客户端下线了");sockets.remove(socket);break;}}}}
}

 

启动服务器
public class serverRun {public static void main(String[] args) {new server();}
}

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

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

相关文章

Windows下nginx的启动,重启,关闭等功能bat脚本

echo off rem 提供Windows下nginx的启动&#xff0c;重启&#xff0c;关闭功能echo begincls ::ngxin 所在的盘符 set NGINX_PATHG:::nginx 所在目录 set NGINX_DIRG:\projects\nginx-1.24.0\ color 0a TITLE Nginx 管理程序增强版CLSecho. echo. ** Nginx 管理程序 *** echo.…

JAVA使用HTTP代码示例

你好&#xff0c;Java开发者们&#xff01;今天&#xff0c;我要给你们带来一场硬核的盛宴&#xff0c;那就是在Java中使用HTTP协议进行网络通信的代码示例。准备好接受挑战了吗&#xff1f;Lets go&#xff01; 首先&#xff0c;我们需要导入一些必要的库&#xff0c;它们将成…

C++枚举类

枚举 C11有作用域枚举和无作用域枚举 无作用域枚举 特点 全局作用域&#xff1a;无作用域枚举的成员&#xff08;枚举值&#xff09;在包含它们的作用域内是直接可见的&#xff0c;不需要使用枚举类型名称作为前缀。 隐式类型转换&#xff1a;无作用域枚举的成员可以隐式地转换…

鸿蒙开发组件之ForEach列表

一、ForEach函数 ForEach函数是一个迭代函数&#xff0c;需要传递两个必须参数和一个可选参数。主要通过迭代来获取参数arr中的数据不断的生成单个Item来生成鸿蒙中的列表样式 二、先创建单个的Item的UI 通过嵌套Row与Column来实现单个Item的UI。例如图中没有折扣的可以看成一…

用23种设计模式打造一个cocos creator的游戏框架----(八)适配器模式

1、模式标准 模式名称&#xff1a;适配器模式 模式分类&#xff1a;结构型 模式意图&#xff1a;适配器模式的意图是将一个类的接口转换成客户端期望的另一个接口。适配器模式使原本接口不兼容的类可以一起工作。 结构图&#xff1a; 适用于&#xff1a; 系统需要使用现有的…

309. 买卖股票的最佳时机含冷冻期(leetcode) 动态规划思想

文章目录 前言一、题目分析二、算法原理1.状态表示2.状态转移方程3.初始化边界条件4.填表顺序5.返回值是什么 三、代码实现总结 前言 在本文章中&#xff0c;我们将要详细介绍一下Leetcode中买卖股票的最佳时机含冷冻期相关的内容&#xff0c;本题采用动态规划的思想解决 一、…

PyQt6 QDateEdit日期控件

​锋哥原创的PyQt6视频教程&#xff1a; 2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 PyQt6 Python桌面开发 视频教程(无废话版) 玩命更新中~共计39条视频&#xff0c;包括&#xff1a;2024版 PyQt6 Python桌面开发 视频教程(无废话…

空中消防员:无人机森林防火应用全面升级

森林是生态系统的重要组成部分&#xff0c;也是人类得以生存的关键。我国森林面积广大&#xff0c;存在火灾频发的困境。提升森林火灾防控能力是维护生态平衡、保护资源和保障人民生命安全的必要步骤。随着无人机技术的发展&#xff0c;其在无人机森林防火中的应用为传统巡查工…

Mybatis与Spring结合深探——MapperFactoryBean的奥秘

文章目录 前言MapperFactoryBean的工作原理底层实现剖析MapperFactoryBean的checkDaoConfig()方法总结 MapperFactoryBean的getObject()方法 思考联想后续 系列相关相关文章究竟FactoryBean是什么&#xff1f;深入理解Spring的工厂神器超硬核解析Mybatis动态代理原理&#xff0…

lv12 开发板启动过程

1 开发板启动过程 1.1 回顾芯片手册第三章内存映射 对于arm来说&#xff0c;不是给它多大的内存都能读。寻址空间&#xff08;地址空间&#xff09;读写范围是有限的&#xff0c;寻址空间的大小与地址总线宽度有关&#xff0c;如32位&#xff0c;地址空间4G&#xff08;2^32)…

【C语言基础】嵌入式面试经典题(C语言篇)----有新的内容会及时补充、更新!

&#x1f4e2;&#xff1a;如果你也对机器人、人工智能感兴趣&#xff0c;看来我们志同道合✨ &#x1f4e2;&#xff1a;不妨浏览一下我的博客主页【https://blog.csdn.net/weixin_51244852】 &#x1f4e2;&#xff1a;文章若有幸对你有帮助&#xff0c;可点赞 &#x1f44d;…

Mac虚拟机CrossOver23破解版下载和许可证下载

CrossOver Mac Mac 和 Windows 系统之间的兼容工具。使 Mac 操作系统的用户可以运行 Windows 系统的应用&#xff0c;从办公软件、实用工具、游戏到设计软件&#xff0c; 您都可以在 Mac 程序和 Windows 程序之间随意切换。 系统要求 运行macOS的基于Intel或Apple Silicon 的…

springboot项目加载配置文件失败

问题 在使用springboot打成jar以后&#xff0c;需要文件加载一个redisson-cluster的配置文件。配置文件是在jar的同级目录。启动时却总是加载jar中的配置文件&#xff0c;而外部配置文件却不加载看下配置&#xff1a;spring:redis:redisson:# redis配置位置file: classpath:red…

lcx iptables rinetd 三个端口转发流量分析

lcx流量分析 环境搭建 本机 &#xff1a;192.168.0.52 win7 &#xff1a; 192.168.0.247 10.0.0.3 win10&#xff1a; 10.0.0.10 win7 Lcx.exe -listen 7777 4444win10 Lcx.exe -slave 10.0.0.3 7777 127.0.0.1 3389然后使用远程软件连接 连的是192.168.0.247的4444 端口 …

基于Pytorch框架深度学的垃圾分类智能识别系统

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 垃圾分类智能识别系统是一种基于深度学习技术的智能系统&#xff0c;用于对垃圾进行分类和识别。它使用Pytorch框架…

【电路笔记】-压敏电阻

压敏电阻 文章目录 压敏电阻1、概述2、交流波形瞬变3、抗静电能力4、特性曲线5、压敏电阻电容值6、金属氧化物压敏电阻7、压敏电阻应用8、总结 压敏电阻是一种无源两端固态半导体器件&#xff0c;用于为电气和电子电路提供保护。 1、概述 与提供过电流保护的保险丝或断路器不同…

Redis高效恢复策略:内存快照与AOF

第1章&#xff1a;Redis宕机恢复的重要性和挑战 大家好&#xff0c;我是小黑。今天咱们来聊聊Redis宕机后的恢复策略。想象一下&#xff0c;你的网站突然宕机了&#xff0c;所有的数据都飘了&#xff0c;这种情况下&#xff0c;快速恢复数据就显得尤为重要。Redis作为一个高性…

大厂算法指南:优选算法 ——双指针篇(下)

大厂算法指南&#xff1a;优选算法 ——双指针篇&#xff08;上&#xff09; 前言&#xff1a;双指针简介一、[611. 有效三角形的个数](https://leetcode.cn/problems/valid-triangle-number/)1.1 算法思路&#xff08;排序 双指针&#xff09;1.2 代码实现 二、[LCR 179. 查找…

[GPT]Andrej Karpathy微软Build大会GPT演讲(下)--该如何使用GPT助手

该如何使用GPT助手--将GPT助手模型应用于问题 现在我要换个方向,让我们看看如何最好地将 GPT 助手模型应用于您的问题。 现在我想在一个具体示例的场景里展示。让我们在这里使用一个具体示例。 假设你正在写一篇文章或一篇博客文章,你打算在最后写这句话。 加州的人口是阿拉…

佳明(Garmin) fēnix 7X 增加小睡检测功能

文章目录 &#xff08;一&#xff09;零星小睡&#xff08;二&#xff09;小睡检测&#xff08;三&#xff09;吐槽佳明&#xff08;3.1&#xff09;心率检测&#xff08;3.2&#xff09;光线感应器&#xff08;3.3&#xff09;手表重量&#xff08;3.4&#xff09;手表续航 &a…