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.rhkb.cn/news/214671.html

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

相关文章

Spring日志完结篇,MyBatis操作数据库(入门)

目录 Spring可以对日志进行分目录打印 日志持久化&#xff08;让日志进行长期的保存&#xff09; MyBatis操作数据库(优秀的持久层框架) MyBatis的写法 开发规范&#xff1a; 单元测试的写法 传递参数 Spring可以对日志进行分目录打印 他的意思是说spring相关只打印INFO…

Truffle的基础语法与js测试语法

truffle编译 truffle compiletruffle部署 truffle migratetruffle测试 使用test文件夹下的所有文件测试 truffle test使用单个文件 测试 truffle test 文件所在位置

机器学习算法(9)——集成技术(Bagging——随机森林分类器和回归)

一、说明 在这篇文章&#xff0c;我将向您解释集成技术和著名的集成技术之一&#xff0c;它属于装袋技术&#xff0c;称为随机森林分类器和回归。 集成技术是机器学习技术&#xff0c;它结合多个基本模块和模型来创建最佳预测模型。为了更好地理解这个定义&#xff0c;我们需要…

[UIM]论文解读:subword Regularization: Multiple Subword Candidates

文章目录 一、完整代码二、论文解读2.1 介绍2.2 NMT2.3 Unigram language model2.4 subword 抽样2.5 效果 三、整体总结 论文&#xff1a;Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates 作者&#xff1a;Taku Kudo 时…

低多边形3D建模动画风格纹理贴图

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 当谈到游戏角色的3D模型风格时&#xff0c;有几种不同的风格&#xf…

什么是神经网络的非线性

大家好啊&#xff0c;我是董董灿。 最近在写《计算机视觉入门与调优》&#xff08;右键&#xff0c;在新窗口中打开链接&#xff09;的小册&#xff0c;其中一部分说到激活函数的时候&#xff0c;谈到了神经网络的非线性问题。 今天就一起来看看&#xff0c;为什么神经网络需…

ThinkPHP连接ORACLE数据库教程

目录 概念基本步骤详细操作问题排除参考 概念 要连接Oracle数据库&#xff0c;必须有两个东西&#xff0c;一个PHP官方写的扩展&#xff0c;一个Oracle官方写的客户端PHP是通过扩展去操作oralce客户端连接的服务端数据库&#xff0c;所以两个都不能少&#xff0c;而且版本必须…

P1005 [NOIP2007 提高组] 矩阵取数游戏

网址&#xff1a;P1005 [NOIP2007 提高组] 矩阵取数游戏 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 动态规划和高精度的组合&#xff0c;使我的滨州旋转 最后只得了80&#xff0c;两个测试点超时了 看题解有人是用了int128来做的&#xff0c;明天学一下 我的递归思路和…

MongoDB的分片

本文主要介绍MongoDB的分片。 目录 MongoDB的分片组成分片过程操作步骤注意事项 MongoDB的分片 MongoDB的分片是一种横向扩展数据库的方式&#xff0c;可以将数据分散存储在多台服务器上&#xff0c;从而提高数据库的处理能力和可用性。 组成 MongoDB的分片由三个组成部分组…

Ansible中执行流控制

1.ansible中的迭代循环 创建目录和文件 vim createfile.yaml - name: create file playbook hosts: all tasks: - name: create file file: path: "/mnt/{{item[name]}}" state: …

scala变量与变量类型

1.6 变量与类型&#xff08;重点&#xff09;1.6.1 变量推断1.6.2 多变量定义1.6.3 var和val的区别 1.6.3.1 是否可变 1.6.3.2 延迟加载 1.6 变量与类型&#xff08;重点&#xff09; val修饰的变量&#xff0c;相当于Java中final修饰的变量; // 定义常量s1&#xff0c;使用…

GPIO的使用--USART串口通信--传感器控制数据

目录 一、串口通信 1、概念 2、原理图 3、使用步骤 &#xff08;1&#xff09;寻找串口位置 &#xff08;2&#xff09;确定引脚编号 &#xff08;3&#xff09;编写代码 4、实验结果 实验代码 main.c usart.c usart.h 一、串口通信 1、概念 串行接口是一种可以将…

GPT-4 变懒了?官方回复

你是否注意到&#xff0c;最近使用 ChatGPT 的时候&#xff0c;当你向它提出一些问题&#xff0c;却得到的回应似乎变得简短而敷衍了&#xff1f;对于这一现象&#xff0c;ChatGPT 官方给出了回应。 译文&#xff1a;我们听到了你们所有关于 GPT4 变得更懒的反馈&#xff01;我…

玩转大数据10:深度学习与神经网络在大数据中的应用

目录 1. 引言&#xff1a;深度学习和神经网络在大数据中的重要性和应用场景 2. 深度学习的基本概念和架构 3. Java中的深度学习框架 3.1. Deeplearning4j框架介绍及Java编程模型 3.2. DL4J、Keras和TensorFlow的集成 4. 大数据与深度学习的结合 4.1. 大数据与深度学…

Redis探秘:AOF日志与数据持久性之旅

第1章&#xff1a;引言 大家好&#xff0c;我是小黑&#xff0c;咱们今天来聊聊Redis。你知道吗&#xff0c;Redis作为一个超高效的内存数据库&#xff0c;真的是超级给力。它可以秒速处理数据&#xff0c;让咱们的应用运行得飞快。但是&#xff0c;小黑得告诉你&#xff0c;虽…

Linux进程地址空间

Linux进程地址空间 一.语言上的内存分区1.内存分区的理论说明2.内存分区的代码验证3.一个"奇怪"的现象 二.进程地址空间1.现象解释2.什么是进程地址空间3.页表的权限属性与重新理解写时拷贝4 .为什么要有进程地址空间和页表5.用进程地址空间解释一些问题1.为何进程之…

android 13.0 去掉recovery模式UI操作页面的菜单选项

1.概述 在13.0进行系统rom定制化开发中,在进行一些定制化开发中,会根据需要在进入recovery模式的时候,去掉recovery模式的一些菜单选项, Reboot to bootloader,Enter rescue等菜单项,经过分析得知, 就是在device.cpp去掉一些菜单选项就可以了,接下来就来分析实现相关功…

从Centos-7升级到Centos-Stream-8

如果在正式环境升级&#xff0c;请做好数据备份以及重要配置备份&#xff01;因为升级会造一部分应用被卸载。 注意&#xff1a;升级前请备份好数据&#xff0c;升级可能会导致ssh的root用户无法登陆、网卡名称发生改变、引导丢失无法开机等问题。 1.安装epel源 yum -y install…

Redis生产实战-Redis集群故障探测以及降级方案设计

Redis 集群故障探测 在生产环境中&#xff0c;如果 Redis 集群崩溃了&#xff0c;那么会导致大量的请求打到数据库中&#xff0c;会导致整个系统都崩溃&#xff0c;所以系统需要可以识别缓存故障&#xff0c;限流保护数据库&#xff0c;并且启动接口的降级机制 降级方案设计 …

【EI征稿中|ACM出版】2023 人工智能、系统与网络安全国际学术会议 (AISNS 2023)

2023 人工智能、系统与网络安全国际学术会议 (AISNS 2023&#xff09; 2023 International Conference on Artificial Intelligence, Systems and Network Security 由西南科技大学计算机科学与技术学院主办的2023人工智能、系统与网络安全国际学术会议 (AISNS 2023&#xff…