Java实例 基于UDP及自建知识库的聊天机器人

这篇具有很好参考价值的文章主要介绍了Java实例 基于UDP及自建知识库的聊天机器人。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Java实例 基于UDP及自建知识库的聊天机器人

01 涉及技术栈

  • GUI界面: Swing组件库+GUI Form布局设计
  • C\S通信: UDP+线程管理
  • 知识库: IO文件读写流+本地.txt文件
  • 日期处理: Data类+SimpleDateFormat类(格式转换)
  • 其他知识: Java基础知识+面向对象编程+String字符串处理+异常处理等

02 运行效果展示

代码已上传仓库,切换分支后拉取。https://gitee.com/strivezhangp/java-demo.git 分支:Chatting

java实现私聊udp,java,udp,开发语言,网络协议,intellij-idea
java实现私聊udp,java,udp,开发语言,网络协议,intellij-idea
java实现私聊udp,java,udp,开发语言,网络协议,intellij-idea
java实现私聊udp,java,udp,开发语言,网络协议,intellij-idea

03 项目目录说明

java实现私聊udp,java,udp,开发语言,网络协议,intellij-idea

04 程序工作流程说明

主要包含以下步骤:

  1. Main()进入程序
  2. 进行登录,输入用户名判断
  3. 判断成功,进入聊天室,同时创建客户端服务端UDP通信进程
  4. 客户端输入文字提问
  5. 服务端收到信息,创建IO流,进行本地知识库的读取,并作出相应的回复
  6. Data()获取当前时间,设置ServerClient的聊天记录的展示

java实现私聊udp,java,udp,开发语言,网络协议,intellij-idea

05 关键知识及代码

此处只展示关键代码,其余代码见Gitee仓库。

(1)文件读写流

包括文件的读写和字符串的处理,涉及到了String类的一些方法:

  • startsWith():判断字符串是否一XX开始
  • substring():字符串的截取(获取子串)

文件读写流相关知识:

  • BufferedReader:带缓冲的字符流的创建使用
  • FileReader:文件读取流的创建使用

集合相关知识:

  • ArrayList:集合的创建以及内容的读取,添加等
package fileIO;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

/**
 * @description: 文件的读写流使用字符缓冲流进行
 * @author:StrivePeng
 */
public class FileIo {
    public static final String FILEPATH = "src/fileIO/知识库.txt";
    private static BufferedReader reader; // 字符缓冲流
    private ArrayList<String> answerList = new ArrayList<String>(); // 存放答案
    private ArrayList<String> questionList = new ArrayList<String>(); // 存放问题

    /**
     * @throws IOException              io异常
     * @throws IllegalArgumentException 文件不符合预期格式
     *                                  构造函数,读取文件数据存放到静态变量
     */
    public FileIo() throws IOException, IllegalArgumentException {
        try {
            reader = new BufferedReader(new FileReader(FILEPATH)); // 初始化字符缓冲器
            findKnowledge(); // 处理文件 存放变量集合中
        } finally {
            if (reader != null) {
                // 关闭资源
                reader.close();
            }
        }
    }

    /**
     * @throws IOException io异常
     * @description: 将知识库中的问题和答案分类存放到响应的数组中
     * @author:StrivePeng
     */
    private void findKnowledge() throws IOException {
        // 按照行读取
        String line;
        while ((line = reader.readLine()) != null) {
            // 判断是问题or答案
            if (line.startsWith("答案")) {
                String answer = line.substring("答案".length()); // 截取后面得字符串
                answerList.add(answer);
            }
            if (line.startsWith("问题")) {
                String question = line.substring("问题".length());
                questionList.add(question);
            }
        }
    }

    public ArrayList<String> getAnswerList() {
        return answerList;
    }

    public ArrayList<String> getQuestionList() {
        return questionList;
    }
}

(2)UDP通信相关

涉及到的一些知识点:

  • 静态常量的创建和使用

  • DatagramSocket 数据流的创建和使用

  • DatagramPacket 数据包的创建和使用

  • 客户端和服务端的意义所在:

    UDP的特性使得它适用于广播通信。如果服务端监听的是广播地址,那么来自同一广播地址的多个客户端都能够发送消息给服务端。但在一般的应用场景中,客户端通常需要明确指定服务端的IP地址和端口号,以确保消息准确到达指定的服务端。

    服务端并没有指定固定的地址,而是通过 DatagramSocket 的构造方法创建了一个未绑定地址的 DatagramSocket。这样做的原因是,服务端通常是被动地等待客户端的连接请求,因此不需要预先指定一个地址。

    服务端使用 server.receive(receivePacket); 接收客户端发送的数据包时,DatagramSocket 会自动绑定到一个系统分配的可用端口,并通过这个端口接收数据。服务端的地址信息会在 receivePacket 中自动填充。

    客户端在发送数据包时,为了指定服务端的地址,需要使用 InetAddress.getByName("127.0.0.1") 来获取服务端的IP地址,同时指定服务端的端口号(在这个例子中是 PORT)。这样客户端的数据包就能够到达服务端指定的地址和端口。

// 客户端
package udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class Client {
    private static final int PORT = 8888; // 固定的端口号
    private DatagramSocket clientSocket; // 未初始化的客户端

    // 构造函数 同时初始化客户端
    public Client() throws Exception {
        clientSocket = new DatagramSocket();
    }

    /**
     * @param message 消息内容
     * @description: 向服务器发送消息
     * @author: strivePeng
     */
    public void clientSendMsg(String message) {
        try {
            InetAddress serverAddress = InetAddress.getByName("127.0.0.1"); // 固定一个客户端IP为 本地
            byte[] sendBuffer = message.getBytes();

            // 创建并发送数据包
            DatagramPacket sendPacket = new DatagramPacket(sendBuffer, sendBuffer.length, serverAddress, PORT);
            clientSocket.send(sendPacket);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}


// 服务端
package udp;

import java.net.DatagramPacket;
import java.net.DatagramSocket;

public class Server {
    private static final int PORT = 8888; // 固定的端口号
    private DatagramSocket server; // 一个未初始化的服务端

    // 构造函数
    public Server() throws Exception {
        server = new DatagramSocket(PORT); // 初始化服务端
    }

    /**
     * @return 返回一个收到的字符串
     * @description: 服务器接收客户端发来的消息
     * @author: strivePeng
     */
    public String serverReceiveMsg() {
        try {
            byte[] receiveBuffer = new byte[1024];

            // 创建并接收数据包 同时转为字符串返回
            DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
            server.receive(receivePacket);
            return new String(receivePacket.getData(), 0, receivePacket.getLength());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

(3)Swing组件的使用

窗口结合IDEA的GUI Form可视化拖动设计。基本的创建步骤如下图所示:

java实现私聊udp,java,udp,开发语言,网络协议,intellij-idea
java实现私聊udp,java,udp,开发语言,网络协议,intellij-idea

Swing组件
  • 常用容器组件:
    • JFrame:顶级窗口容器,用于创建窗口。
    • JPanel:用于创建面板,可将组件添加到面板中。
    • JDialog:对话框容器,用于创建弹出式对话框。
  • 基本组件:
    • JButton:按钮。
    • JLabel:标签。
    • JTextField:文本框。
    • JTextArea:多行文本框。
    • JCheckBox:复选框。
    • JRadioButton:单选按钮。

当学习 Java Swing 时,深入了解各个组件的特性、属性以及适用场景是非常重要的。以下是对几个常用 Swing 组件的详细介绍:

JFrame:顶级窗口容器
  • 特性:
    • 用于创建窗口应用程序的主窗口。
    • 可以包含其他 Swing 组件。
    • 提供了标题栏、菜单栏等标准窗口元素。
  • 属性:
    • setTitle(String title):设置窗口标题。
    • setSize(int width, int height):设置窗口的大小。
    • setDefaultCloseOperation(int operation):设置关闭窗口的操作。
    • setLocationRelativeTo(null); :将窗口定位到屏幕的中央。这是为了确保窗口在屏幕上居中显示。
  • 适用场景:
    • 创建独立的窗口应用程序。
    • 包含其他 Swing 组件,构建完整的应用。
JPanel:面板容器
  • 特性:
    • 用于组织和布局其他组件。
    • 可以嵌套在其他容器中,如 JFrame。
    • 提供了轻量级容器,不具备窗口功能。
  • 属性:
    • setLayout(LayoutManager manager):设置布局管理器。
    • add(Component comp):添加组件到面板。
  • 适用场景:
    • 作为容器,组织其他组件。
    • 嵌套在 JFrame 中,实现复杂的界面布局。
JButton:按钮
  • 特性:
    • 用于触发用户操作的按钮。
    • 可以包含文本、图标等。
    • 通过监听器响应点击事件。
  • 属性:
    • setText(String text):设置按钮上的文本。
    • setIcon(Icon icon):设置按钮上的图标。
    • addActionListener(ActionListener listener):添加点击事件监听器。
  • 适用场景:
    • 作为用户交互的触发器。
    • 触发表单提交、对话框弹出等操作。
JLabel:标签
  • 特性:
    • 用于显示文本或图像。
    • 可以用于展示静态信息。
    • 不响应用户输入。
  • 属性:
    • setText(String text):设置标签显示的文本。
    • setIcon(Icon icon):设置标签显示的图标。
  • 适用场景:
    • 展示静态文本或图像。
    • 用于显示提示信息。
JTextField:文本框
  • 特性:
    • 用于接收用户输入的单行文本。
    • 可以设置初始文本。
    • 通过监听器响应文本变化事件。
  • 属性:
    • setText(String text):设置文本框的初始文本。
    • getText():获取文本框的当前文本。
  • 适用场景:
    • 接收用户输入的文本信息。
    • 用于登录、搜索等场景。
JTextArea:多行文本框
  • 特性:

    • 用于接收用户输入的多行文本。
    • 可以设置初始文本和行数。
    • 通过监听器响应文本变化事件。
  • 属性:

    • setText(String text):设置多行文本框的初始文本。
    • getText():获取多行文本框的当前文本。
  • 适用场景:

    • 接收用户输入的多行文本信息。

    • 用于评论、描述等场景。

    • 布局管理器(Layout Managers)
      • 特性:
        • 用于确定组件在容器中的位置和大小。
        • 常见的有 FlowLayoutBorderLayoutGridLayoutBoxLayout 等。
        • 可以嵌套使用,实现复杂的布局。
      • 适用场景:
        • 定义和控制组件的相对位置。
        • 适配不同屏幕尺寸和分辨率。

(4)类对象的引用

除此之外,在登录成功后涉及到了弹窗的关闭,此时使用了类对象的引用的传入,方便销毁登录界面。具体实现如下。

 // 构造函数 同时传入登录界面的引用方便在登录成功后关闭
    public LoginSuccessfulDialog(LoginJF loginJF) {
        this.loginJF = loginJF; // 传入一个窗口对象的引用
        this.setTitle("提示");
        this.setContentPane(contentPane);
        this.setModal(true);
        this.getRootPane().setDefaultButton(buttonOK);

        // 判断用户是否存在
        if(loginJF.userIsExit){
            // 用户存在
            this.successfulDialog.setText("登录成功!");
            // 设置按钮功能为点击后跳转到聊天界面
            this.buttonOK.addActionListener(actionEvent -> onOK());
        }else{
            // 用户不存在
            this.successfulDialog.setText("登录失败,请重新登录!");
            this.buttonOK.addActionListener(actionEvent -> onCancel());
        }
        ......
    }

(5)线程调用GUI窗口

    public static void main(String[] args) {
        /*
        使用了 SwingUtilities.invokeLater() 方法来确保 Swing 组件的初始化和显示操作在事件分派线程(Event Dispatch Thread,EDT)上执行。
        在 Swing 中,GUI 的相关操作应该在 EDT 上执行,以确保线程安全性。
         */
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                LoginJF loginJF = new LoginJF();
                loginJF.setVisible(true);
            }
        });
    }

(6)Lambda表达式的使用

Lambda 表达式是 Java 8 中引入的一个强大的特性,它提供了一种更简洁、更方便的方式来实现函数式编程。Lambda 表达式通常在简单的、只有一个抽象方法的接口中发挥作用,使代码更为紧凑。Lambda 表达式的主要用途是简化匿名内部类的语法,使代码更加紧凑和易读。下面详细讲解 Lambda 表达式的用法:

基本语法

Lambda 表达式的基本语法如下:

(parameters) -> expression

或者

(parameters) -> { statements; }
  • (parameters):指定参数列表。如果没有参数,可以留空或使用 ()
  • ->:称为箭头操作符,将参数列表与 Lambda 表达式的主体分隔开。
  • expression:Lambda 表达式的主体,可以是单个表达式。
  • { statements; }:Lambda 表达式的主体,可以是一系列语句。
程序中的使用
// 按钮监听事件绑定
this.resetButton.addActionListener(actionEvent -> reset());

// 判断用户是否存在
if(loginJF.userIsExit){
    // 用户存在
    this.successfulDialog.setText("登录成功!");
    // 设置按钮功能为点击后跳转到聊天界面
    this.buttonOK.addActionListener(actionEvent -> onOK());
}else{
    // 用户不存在
    this.successfulDialog.setText("登录失败,请重新登录!");
    this.buttonOK.addActionListener(actionEvent -> onCancel());
}

// 开启聊天界面
SwingUtilities.invokeLater(()->{
    ChattingJF chattingJF = new ChattingJF();
    chattingJF.setVisible(true);
});

(7)日期获取与处理

/**
 * @return 当前日期的字符串
 * @description 获取当前时间并格式化为字符串
 * @author strivePeng
 */
private String getCurrentTime() {
    // 格式化日期 SimpleDateFormat
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH:mm:ss");
    // 获取当前日期
    Date data = new Date(System.currentTimeMillis());
    // 格式化日期时间转为字符串
    String str = sdf.format(data);
    return str;
}

(8)知识库中的答案的搜索与展示

涉及到了更多的String字符串的处理以及List集合的操作,详见代码注释:

/**
 * @param question 提问的问题
 * @return 服务器返回的答案
 * @throws IOException 文件IO异常
 * @description 从知识库中返回答案
 * @author strivePeng
 */
private String findAnswer(String question){
    try{
        FileIo fileIo = new FileIo();
        for (String q : fileIo.getQuestionList()) {
            if (question.trim().equals(q.trim())) {
                // 根据问题和答案的索引一一对应的关系返回答案
                return fileIo.getAnswerList().get(fileIo.getQuestionList().indexOf(q));
            }
        }
    }catch (Exception e){
        e.printStackTrace();
    }
    return "抱歉!我还没有学习到这方面的知识哦!!!";
}

06 结语

聊天机器人相关知识详情都在源码注释中详细备注,本次练习旨在为自己一阶段的学习进行检验,在本次实例中使用到了java基础的语法,以及异常处理,一小部分的线程处理,以及Swing组件的使用和文件的读写流等,适合新手上手以及对网路UDP通信的理解。

前期的学习参考了以下博客:CSDN博客文章来源地址https://www.toymoban.com/news/detail-772249.html

到了这里,关于Java实例 基于UDP及自建知识库的聊天机器人的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • chatglm实现基于知识库问答的应用

    目前由于ChatGPT横空出世,互联网如雨后春笋冒出了非常多的类ChatGPT的大型语言模型。但是对于这些语言模型,我们应该如何将它应用到我们实际的生产中需要一个更加成熟的解决方案。 本文旨在通过介绍ChatGLM的使用来讲述如何将一个开源的语言模型应用于智能问答,知识库

    2024年02月06日
    浏览(33)
  • 基于大语言模型知识问答应用落地实践 – 知识库构建(下)

    上篇介绍了构建知识库的大体流程和一些优化经验细节,但并没有结合一个具体的场景给出更细节的实战经验以及相关的一些 benchmark 等,所以本文将会切入到一个具体场景进行讨论。 目标场景:对于 PubMed 医疗学术数据中的 1w 篇文章进行知识库构建,实现快速的注入和查

    2024年02月10日
    浏览(48)
  • 大语言模型也是知识库:基于知识的对话大模型综述

    ©PaperWeekly 原创 · 作者 | 缥缈孤鸿影 引言 ChatGPT 的横空出世,在整个自然语言处理乃至人工智能领域均掀起波澜。不同于普通的闲聊式机器人和任务型智能客服仅局限于固定场景,ChatGPT 具有相当丰富的知识储备,对于很多冷门的知识,它亦能对答如流,堪称当代“百晓生”

    2024年02月09日
    浏览(49)
  • ai聊天问答知识库机器人源码,基于gpt实现的本地知识库问答实现,聊天对话效果,发送回复以及流式输出...

    现在基于gpt做自己项目的问答机器人,效果非常的好。可以把自己的文档上传上去,让机器人根据文档来进行回答。 想要实现智能AI问答功能,现在大部分都是基于向量数据库的形式。 整体的流程就是:上传文档===openai向量接口 ==== 存入向量数据库 访客咨询:  咨询问题

    2024年02月10日
    浏览(46)
  • 基于 InternLM 和 LangChain 搭建你的知识库

    如何打造垂域大模型是一个重要落地方向。 如何打造个人专属的大模型应用也是重要的问题。 RAG 外挂一个知识库 优势:成本低,实时更新 劣势:能力受基座模型影响大,RAG每次需要将检索文档和问题提交给大模型,极大占用上下文限制。 Finetune 轻量级的微调 优势:可以充

    2024年01月19日
    浏览(51)
  • 基于Azure OpenAI Service 的知识库搭建实验⼿册

    1. 概要         介绍如何使⽤Azure OpenAI Service 的嵌⼊技术,创建知识库;以及创建必要的资源组和资源,包括 Form Recognizer 资源和 Azure 翻译器资源。在创建问答机器⼈服务时,需要使⽤已部署模型的 Azure OpenAI 资源、已存在的表格识别资源和翻译资 源。通过 Azure ⾃定义资

    2024年02月14日
    浏览(38)
  • 【LangChain学习】基于PDF文档构建问答知识库(二)创建项目

    这里我们使用到 fastapi 作为项目的web框架,它是一个快速(高性能)的 web 框架,上手简单。 我们在IDE中,左侧选择 FastAPI ,右侧选择创建一个新的虚拟环境。  创建成功,会有一个main.py,这是项目的入口文件。  我们运行一下看看有没有报错,没问题的话,那么我们整合

    2024年02月13日
    浏览(58)
  • 【LangChain学习】基于PDF文档构建问答知识库(一)前期准备

    这系列主要介绍如何使用LangChain大模型,结合ChatGPT3.5,基于PDF文档构建专属的问答知识库。 LangChain 和 OpenAI 本身可支持 Nodejs 和 Python 两个版本,笔者后续的介绍主要用到Python版本,如果有需要Nodejs版本的同学,也可以给我留言,因为Nodejs版本我也实现了。 Python 版本为 ≥

    2024年02月13日
    浏览(63)
  • 【基于 InternLM 和 LangChain 搭建你的知识库】学习笔记

    学习参考文档【基于 InternLM 和 LangChain 搭建你的知识库】 学习参考链接【书生・浦语大模型实战营第三课作业(基础+进阶)】 收集2018年-2020年几年间的优秀数学建模论文 LangChain 相关环境配置 下载 NLTK 相关资源 下载相关仓库 脚本文件 Web Demo部署

    2024年02月01日
    浏览(45)
  • 基于闻达(wenda+chatGLM-6B),构建自己的知识库小助手

    目录 安装miniconda 拉取仓库 使用内置python 安装依赖 上传模型 克隆及下载 text2vec-large-chinese 修改配置 上传知识库(txt文件) 处理txt数据 启动服务 测试 ChatGLM-6B是清华团队+智谱AI开发的,一个开源的、支持中英双语的对话语言模型,具有 62 亿参数。被很多人视为ChatGPT的平替

    2024年02月06日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包