java实现网络聊天

news2024/11/26 20:23:21

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

客户端:

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() {
            @Override
            public 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() {
            @Override
            public 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() {
            @Override
            public 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());

       }

        @Override
        public 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() {
            @Override
            public 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());
        }

        @Override
        public 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.coloradmin.cn/o/1300942.html

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

相关文章

详细介绍开源固件-TF-A

什么是TF-A&#xff1f; TF-A&#xff08;Trusted Firmware-A&#xff09;是一种用于嵌入式系统的开源固件&#xff0c;而不是Linux的一部分。TF-A主要用于ARM架构的处理器和设备&#xff0c;它提供了一组安全和可信任的软件组件&#xff0c;用于引导和初始化系统。 如下是其…

学习通【劳动通论】2023章节练习题

社会主义核心价值观24个字是&#xff1a;富强、民主、文明、和谐&#xff0c;自由、平等、公正、法治&#xff0c;爱国、敬业、诚信、友善。 1、“富强、民主、文明、和谐”&#xff0c;是我国社会主义现代化国家的建设目标&#xff0c;也是从价值目标层面对社会主义核心价值观…

基于Java Swing泡泡龙游戏(Java毕业设计)

大家好&#xff0c;我是DeBug&#xff0c;很高兴你能来阅读&#xff01;作为一名热爱编程的程序员&#xff0c;我希望通过这些教学笔记与大家分享我的编程经验和知识。在这里&#xff0c;我将会结合实际项目经验&#xff0c;分享编程技巧、最佳实践以及解决问题的方法。无论你是…

uniapp iOS离线打包——运行项目到模拟器报错?

运行项目、打包时报错问题 记录个人在开发过程中遇到的相关问题&#xff0c;后续有时间会不定时更新 文章目录 运行项目、打包时报错问题运行到模拟器报错解决方案 打包报错解决方案 运行到模拟器报错 解决方案 选中项目工程 —> Build Settings 滑动底部 —> User-Defi…

3.DevEco Studio安装鸿蒙手机app本地模拟器

配合Intel CPU启动模拟器 解决措施 打开任务管理器&#xff0c;在“性能”选项&#xff0c;检查CPU虚拟化是否已经启用。如果未启用&#xff0c;需要进入电脑的BIOS中&#xff0c;将CPU的“Intel Virtualization Technology”选项开启。 点击New Emulator 文档中心 解决措施…

048:利用vue-video-player播放m3u8

第048个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

pyqt5使用Designer实现按钮上传图片

pyqt5使用Designer实现按钮上传图片 1、ui界面 2、ui转py代码 其中uploadimg.py代码如下&#xff1a; # -*- coding: utf-8 -*-# Form implementation generated from reading ui file uploadimg.ui # # Created by: PyQt5 UI code generator 5.15.4 # # WARNING: Any manua…

【小沐学Python】Python实现TTS文本转语音(speech、pyttsx3、百度AI)

文章目录 1、简介2、Windows语音2.1 简介2.2 安装2.3 代码 3、pyttsx33.1 简介3.2 安装3.3 代码 4、ggts4.1 简介4.2 安装4.3 代码 5、SAPI6、SpeechLib7、百度AI8、百度飞桨结语 1、简介 TTS(Text To Speech) 译为从文本到语音&#xff0c;TTS是人工智能AI的一个模组&#xf…

【unity实战】一个通用的FPS枪支不同武器射击控制脚本

文章目录 前言模型素材文章用到的粒子火光特效射击效果换弹瞄准开枪抖动效果设置显示文本最终代码不同武器射击效果1. 手枪2. 机枪3. 狙击枪4. 霰弹枪5. 加特林 其他感谢完结 前言 实现FPS枪支不同武器效果&#xff0c;比如手枪&#xff0c;喷子&#xff0c;狙击枪&#xff0c…

Dubbo入门直接上手,结合微服务详解

Dubbo 高性能、轻量级的 Java RPC 框架 RPC&#xff1a; Remote Procedure Call 远程过程调用&#xff0c;简单来说就是它允许一个计算机程序通过网络请求调用另一个计算机上的程序&#xff0c;就像本地调用一样。有非常多的协议和技术来都实现了RPC的过程&#xff0c;比如&a…

MySQL数据库,创建和管理表

创建数据库&#xff1a; 方式一&#xff1a;创建数据库 CREATE DATABASE 数据库名&#xff1b;&#xff08;使用的是默认的字符集&#xff09; 方式二&#xff1a;创建数据库并指定字符集 CREATE DATABASE 数据库名 CHARACTER SET 字符集&#xff1b; 方式三&#xff1a;判断数…

【原创】【一类问题的通法】【真题+李6卷6+李4卷4(+李6卷5)分析】合同矩阵A B有PTAP=B,求可逆阵P的策略

【铺垫】二次型做的变换与相应二次型矩阵的对应&#xff1a;二次型f&#xff08;x1&#xff0c;x2&#xff0c;x3&#xff09;xTAx&#xff0c;g&#xff08;y1&#xff0c;y2&#xff0c;y3&#xff09;yTBy ①若f在可逆变换xPy下化为g&#xff0c;即P为可逆阵&#xff0c;有P…

【大数据】Hudi 核心知识点详解(二)

&#x1f60a; 如果您觉得这篇文章有用 ✔️ 的话&#xff0c;请给博主一个一键三连 &#x1f680;&#x1f680;&#x1f680; 吧 &#xff08;点赞 &#x1f9e1;、关注 &#x1f49b;、收藏 &#x1f49a;&#xff09;&#xff01;&#xff01;&#xff01;您的支持 &#x…

设计模式篇---代理模式

文章目录 概念结构实例静态代理动态代理 总结 概念 代理模式&#xff1a;给某一个对象提供一个代理或占位符&#xff0c;并由代理对象来控制对原对象的访问。 比如我们想从其他国家买东西&#xff0c;但我们无法直接联系外国的商家&#xff0c;可以找代理商&#xff0c;让他们…

ipa文件怎么去除包体内的插件在线签名工具步骤

当开发者完成iOS应用的开发并构建完成后&#xff0c;应用程序会被打包为一个.ipa文件&#xff0c;这是一个iOS App Store的安装包格式。在某些情况下&#xff0c;开发者可能需要去除.ipa文件中包含的插件&#xff08;通常指的是app extension、frameworks或watch apps等&#x…

内测分发是什么?十年的前端开发者带你了解

内测分发是软件开发过程中的一个阶段&#xff0c;特别指软件还未完全完成或准备对外广泛发布前&#xff0c;向一定范围的用户群体提供该软件版本的测试机会&#xff0c;以便收集反馈和修复潜在的问题。在讲解内测分发之前&#xff0c;我们需要明确几个相关概念&#xff1a; 软件…

12.视图

目录 1.视图的含义与作用 2.视图的创建与查看 1.创建视图的语法形式 2、查看视图&#xff1a; 1.使用DESCRIBE语句查看视图基本信息 2.使用SHOW TABLE STATUS语查看视图基本信息查看视图的信息 3.使用SHOW CREATE VIEW语查看视图详细信息 4.在views表中查看视图详细信息…

23.12.10日总结

周总结 这周三的晚自习&#xff0c;学姐讲了一下git的合作开发&#xff0c;还有懒加载&#xff0c;防抖&#xff0c;节流 答辩的时候问了几个问题&#xff1a; 为什么在js中0.10.2!0.3? 在js中进行属性运算时&#xff0c;会出现0.10.20.300000000000000004js遵循IEEE754标…

DIP——边缘提取与分割

1.使用canny算法进行边缘提取 本实验比较简单&#xff0c;基本思路是对原图像进行一个高斯模糊处理&#xff0c;用于去噪&#xff0c;之后转换为灰度图&#xff0c;直接调用cv库中的canny记性边缘提取。若想直接得到彩色边缘&#xff0c;则通过按位与操作&#xff0c;将原始彩色…

docker-centos中基于keepalived+niginx模拟主从热备完整过程

文章目录 一、环境准备二、主机1、环境搭建1.1 镜像拉取1.2 创建网桥1.3 启动容器1.4 配置镜像源1.5 下载工具包1.6 下载keepalived1.7 下载nginx 2、配置2.1 配置keepalived2.2 配置nginx2.2.1 查看nginx.conf2.2.2 修改index.html 3、启动3.1 启动nginx3.2 启动keepalived 4、…