【网络编程通关之路】 Udp 基础回显服务器(Java实现)及你不知道知识原理详解 ! ! !

news2024/9/22 11:38:12

本篇会加入个人的所谓鱼式疯言

❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言

而是理解过并总结出来通俗易懂的大白话,

小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.

🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人能接受我们这个概念 !!!

引言

在这个信息爆炸的时代,数据传输的速度和效率比以往任何时候都更加重要。想象一下,你正在观看一场在线直播的体育赛事,突然画面卡顿,数据包丢失——这可能是由于TCP协议的重传机制导致的延迟。

但如果你使用的是 UDP,情况可能会完全不同。UDP,即用户数据报协议,以其轻量级和低延迟的特性,在网络编程中扮演着重要角色。本文将深入探讨UDP的工作原理,以及它如何为现代网络通信带来革命性的变化。

目录

  1. Udp与Tcp 协议

  2. Udp服务器的实现过程及原理

  3. Udp客户端的实现过程及原理

  4. 回显服务器的原理剖析及扩展字典服务器功能

一. Udp 与 Tcp 协议

1. Udp 与 Tcp 的初识

在这里插入图片描述

Udp 和 Tcp 都是 Tcp / IP 五层协议中的 第四层: 传输层 , 主要提供在不同主机上提供进程和进程的 传输服务 , 主要还是关注传输的 起点和终点

2. Udp 的特点 和 Tcp的特点

Udp: 无连接, 不可靠, 面向 数据报, 全双工。

Tcp: 有连接, 可靠, 面向 字节流, 全双工

  • 连接性:连接的含义: 不是实际意义上的两根线连起来,而是一种 抽象的连接 , 就是说通信双方都保存着对方的 信息(IP地址, 端口号)

    对于Udp 来说是无连接的,也就是 没有 保存 对方信息的一种连接特性。

    对于Tcp 来说是有连接的, 也就是 保存着 对方信息 的一种连接特性。

  • 可靠性 : 对于网络通讯来说可靠 不是百分百通信, 而不丢失数据 。 可靠性的关键就在于当 数据发送错误或出现数据丢失 的情况, 是否会进行 重传 数据。

    对于 Tcp 来说, 是有 应答响应和延时重传机制的(重点内容后面文章详解), 当网络数据发生影响时, 就会进行 重传防止数据的丢失

    对于 Udp 来说, 是没有的, 当网络通信出现问题时, 就会进行直接把这段数据直接丢弃, 不会发生重传

  • 面向数据报与面向字节流: 这是两次不同协议的 传输单位 的不同

    对于Tcp 来说 , 面向字节流就等同于一个字节一个字节传输

    好比现有一堆数据, 总有二百个字节单位的数据

    如果你一个一个字节的传输, 需要传输两百次;

    如果你十个十个字节的传输, 需要传输二十次;

    如果你二十个字节的传输, 需要传输十次;

    如果你一百个字节的传输, 就需要传输两次;

    如果你二百个字节的传输, 就需要传输一次。

    对于Udp 来说, 是面向数据报的, 这里的数据报还比挖菜需要用锄头, 砍柴需要用斧头一样, 是一种 专门 为网络通信传输构造的一种 特殊结构的传输单位

    我们只需要构造好 数据报, 把需要传输的数据当 成一个整体 打包成 数据报 即可。

  • 全双工与半双工 : 双工本质上就是一种 传输的方向 , 无论是Tcp 和 Udp , 都是全双工, 其含义就是,无论对于这两种协议部署到主机上, 既可以 发送数据, 也可以 接受数据, 既可以 发送请求, 也可以 对请求做出响应 。 可以认为是一种双方向的

    而半双工就是部署好协议之后, 这个通信设备要么 只能接受数据 , 要么只能发送数据, 而 不能同时接受数据和发送数据, 是以一种 单向 的形式传输。

二. Udp服务器的实现过程及原理

1. 引入

在这里插入图片描述

介绍完Tcp和Udp的特点之后,下面就开始上场本篇文章的核心内容,带着小伙伴们一起实践利用 Udp 协议写一个 回显服务器程序

什么是 回显 ???

就是这个服务器响应给客户端的是 客户端自身发来的请求 , 服务器这边不做业务/ 逻辑上 的处理, 而是直接把 原请求数据 响应返回给客户端

对于Udp 来说, 如果需要进行网络通信就需要调用 系统原生api 来进行实现 , 就需要了解 系统原生api 的使用细节, 但对于Java程序猿来说, JDK早已把 api 进行封装, 封装成 两个类: DatagramSocket , DatagramPacket 。 这两个类都来自于 Java.net 这个包中。

DatagramSocket 相关方法:
在这里插入图片描述

上述 对 DAtagramSocket 实例化一个 Socket 对象时, 我们就是利用这个 Socket 对象 来对 网卡进行操作 , 从而进行 网络通信的必要操作

DatagramPacket 相关方法:

在这里插入图片描述

DatagramPacket 则是上面谈及的数据报, 每实例化一个数据报时, 就要传入对于的 byte[] 数组作为参数, 打包成 一个整体的数据报单元 进行传输。

想必小伙伴们应该还没有理解吧, 下面的原理部署和代码演示讲带着大伙熟悉这些方法的使用 💖 💖 💖 💖 💖

2. 服务器端代码演示

package network;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;


public class MyServer {

    // 定义一个 数据包插口
   private   DatagramSocket socker  = null;


   // 构造方法
    public MyServer(int port) throws SocketException {
        // 进行进程和 端口号的连接
        socker = new DatagramSocket(port);

    }


    public void start()  throws IOException {

            while(true) {
                System.out.println("服务器开始运行...");

//        打包数据包基本单位
                DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096 );

//        接受客户端发来的数据
                socker.receive(requestPacket);

                // 转为成字符串打印日志
                String request = new String(requestPacket.getData(), 0, requestPacket.getLength());


                // 执行业务逻辑并对客户端进行响应
                String response = process(request);


//              打包一组响应的数据包
//            注意这里要带上对应客户端输入的ip地址和端口号
                DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),0, response.getBytes().length,
                        requestPacket.getSocketAddress());

                // 进行响应回服务器中
                socker.send(responsePacket);

                // 打印日志
                System.out.printf("[ip地址为:%s, %s,端口号为:%d, %d 客户端的的需求的为: %s, 服务器的响应为: %s]\n",
                        requestPacket.getAddress(),responsePacket.getAddress(), responsePacket.getPort(),requestPacket.getPort(), request, response);
            }
    }



    // 业务逻辑的方法
    public String process(String request) {
        return request;
    }



    public static void main(String[] args) throws IOException{
        MyServer  myServer = new MyServer(9090);
        myServer.start();
    }
}

3. 服务器端代码流程讲解

对于服务器这端来说:

整体 分为五部:

  1. 实例化 DatagramSocket 并以端口号作为 构造方法的参数 建立 端口号与进程 的连接。
    // 定义一个 数据包插口
   private   DatagramSocket socker  = null;




   // 构造方法
    public MyServer(int port) throws SocketException {
        // 进行进程和 端口号的连接
        socker = new DatagramSocket(port);

    }
  1. 打包一个数据包用来 接收客户端 发来的 请求
//        打包数据包基本单位
                DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096 );

//        接受客户端发来的数据
                socker.receive(requestPacket);
  1. 处理一定的业务逻辑, 由于我们这里是 回显服务器 ,只返回请求结果成为 服务器响应的内容 即可。
     // 执行业务逻辑并对客户端进行响应
            String response = process(request);


// 业务逻辑的方法
public String process(String request) {
    return request;
}
  1. 构造一个 数据包 (带上效应的内容,长度, 以及地址) 用于把 服务器效应 发送回 服务器。
//              打包一组响应的数据包
//            注意这里要带上对应客户端输入的ip地址和端口号
                DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),0, response.getBytes().length,
                        requestPacket.getSocketAddress());

                // 进行响应回服务器中
                socker.send(responsePacket);
  1. 将 客户端的 IP地址, 客户端的 端口号请求效应打印 出来。
            // 打印日志
            System.out.printf("[ip地址为:%s, %s,端口号为:%d, %d 
            客户端的的需求的为: %s, 服务器的响应为: %s]\n",
                    requestPacket.getAddress(),responsePacket.getAddress(), 
responsePacket.getPort(),requestPacket.getPort(), request, response);
        }
}

鱼式疯言

  1. 由于 网络通信 需要的是 服务器和客户端 同时交互 才能展示效果,所以小伙伴们一定要记住只有两台机子以上才能完成 回显服务器 的实现。
  1. 端口号与进程 进行连接时, 需要注意的是:

    一个 进程能连接 多个 端口号

    但是 一个 端口号只能连接 一个 进程。

  1. 在获取 IP地址端口号 打印时, 就需要通过Socket 的对象:responsePacket / requestPacket , 这两个数据报中不仅包含 数据内容 , 还含有 客户端地址和端口号 等… 各种需要传递的信息。
  1. 最后还需要注意一点: Udp是 无连接 的特点, 所以当我们需要发送一个 请求/ 响应 时, 就需要在 对应的数据报 中加入 IP地址和端口号,用来指明需要发送到哪里?

三. Udp客户端的实现过程及原理

Udp 的实现 还是利用 DatagramSocketDatagramPacket 两个类来实现, 大体上的实现过程是 相似的 ,但有 细微之处不相同

在这里插入图片描述

下面我们来看看吧 💖 💖 💖 💖

1. 客户端的代码展示


package network;


import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;


public class MyClient {

    // 服务器ip
    private String serverIp ;

    // 服务器的端口号
    private int serverPort;

    // 创建一个客户端的插口
    private  DatagramSocket clientSocket =  null;



    public MyClient(String serverIp , int serverPort) throws SocketException {

        // 对该服务器的ip 和端口号进行赋值
        this.serverIp = serverIp;
        this.serverPort = serverPort;

        // 连接时,无须指定参数
        clientSocket = new DatagramSocket();

    }

    public void start() throws IOException{
       while(true) {
           System.out.println("客户端开始运行...");
           Scanner in= new Scanner(System.in);

           System.out.print("请输入你的需求: ");
//        输入
           String request = in.next();

           // 打包成 数据量基本单位
           // 并指定 ip 和 端口号
           DatagramPacket  requestPacket =  new 
           DatagramPacket(request.getBytes(), 
           request.getBytes().length, 
InetAddress.getByName(this.serverIp), this.serverPort);

           // 发送给服务器
           clientSocket.send(requestPacket);

           // 构造一个数据包基本单位接受服务器的响应
           DatagramPacket receivePacket = new DatagramPacket(
new byte[4096],4096);

           // 开始接收
           clientSocket.receive(receivePacket);

           System.out.println("最终服务器的效应为: ");

           // 输出日志
           String receive =new String(receivePacket.getData(),
0, receivePacket.getLength());

           System.out.println(receive);
       }

    }

    public static void main(String[] args) throws IOException {
        MyClient myClient = new MyClient("127.0.0.1",9090);
        myClient.start();
    }


}


在这里插入图片描述

在这里插入图片描述

2. 客户端的代码流程讲解

  1. 先实例化一个 Socket 对象 , 并得到 需要发送 服务器IP地址和端口号

public MyClient(String serverIp , int serverPort) throws SocketException {

    // 对该服务器的ip 和端口号进行赋值
    this.serverIp = serverIp;
    this.serverPort = serverPort;

    // 连接时,无须指定参数
    clientSocket = new DatagramSocket();

}
  1. 在控制台中 输入需求 ,并打包成 数据报 (带上数据内容, IP地址, 以及端口号) , 然后利用 Socket 对象进行发送。
        System.out.println("客户端开始运行...");
           Scanner in= new Scanner(System.in);

           System.out.print("请输入你的需求: ");
//        输入
           String request = in.next();

           // 打包成 数据量基本单位
           // 并指定 ip 和 端口号
           DatagramPacket  requestPacket =  new 
           DatagramPacket(request.getBytes(), request.getBytes().length,
            InetAddress.getByName(this.serverIp), this.serverPort);

           // 发送给服务器
           clientSocket.send(requestPacket);
  1. 构造一个 数据报 用来接受服务器 返回的响应
 // 构造一个数据包基本单位接受服务器的响应
           DatagramPacket receivePacket = new DatagramPacket(
new byte[4096],4096);

           // 开始接收
           clientSocket.receive(receivePacket);
  1. 打印 服务器响应 的日志
           // 输出日志
           String receive =new String(receivePacket.getData(),
0, receivePacket.getLength());

           System.out.println(receive);

鱼式疯言

补充细节

  1. 对于客户端这端来说, 当 实例化Socket 时, 是不需要指定 端口号 的, 因为系统就根据客户端的 空缺的端口号 自动默认分配 一个端口号
    如果 程序猿来 分配分配进程 就有可能造成 某个端口号正在忙碌, 就会出现 一个端口号绑定多个进程 的情况,就会参生 BUG
  1. 由于我们传入的IP 地址是 一个字符串 , 我们就需要转换为对于的 点分十进制 的地址表示方式: InetAddress.getByName(this.serverIp)
  1. 异常 SocketException 属于 IOException子类

四. 回显服务器的原理剖析及扩展字典服务器功能

1. 回显服务器的原理剖析

具体 回显服务器 的流程小编用 图示 的方式表示啦,

  • 服务端等待客户端发送请求
    在这里插入图片描述

  • 客户端发送以及阻塞等待

    在这里插入图片描述

  • 返回客户端的响应
    在这里插入图片描述

  • 整体的流程:
    在这里插入图片描述

鱼式疯言

  1. 从构造数据报的内容,我们可以看出 Udp面向数据报 的特点
  1. 从每次发送请求,或者返回响应都需要 设定IP地址和端口号 , 可以看出 Udp 无连接需要手动设置 IP 和端口号 的特点。
  1. 从客户端 既可以发送请求又可以接收响应 , 并且 服务器既可以接收请求,发送响应 , 充分说明 Udp是 全双工传输 的特点。

关于 Udp 不可靠传输 这个特点,这是一个难点也是重点, 小编会在后面的文章中重点详细的

2. 字典服务器功能

服务器:

package network;

import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;





public class MyDicServer extends MyServer{

    private Map<String,String> map = new HashMap<>();

    public MyDicServer(int port) throws SocketException {
        super(port);
        map.put("cat","小猫");
        map.put("dog", "小狗");
        map.put("dusk", "小鸭");
    }

    @Override
    public String process(String request) {
        return  map.getOrDefault(request,"未知单词");
    }

    public static void main(String[] args) throws IOException {
        MyServer m = new MyDicServer(9090);
        m.start();
    }
}

客户端

 package network;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;


public class MyServer {

    // 定义一个 数据包插口
   private   DatagramSocket socker  = null;


   // 构造方法
    public MyServer(int port) throws SocketException {
        // 进行进程和 端口号的连接
        socker = new DatagramSocket(port);

    }


    public void start()  throws IOException {

            while(true) {
                System.out.println("服务器开始运行...");

//        打包数据包基本单位
                DatagramPacket requestPacket = 
                new DatagramPacket(new byte[4096],
                        4096 );

//        接受客户端发来的数据
                socker.receive(requestPacket);

                // 转为成字符串打印日志
                String request = new String(requestPacket.getData(),
                        0, requestPacket.getLength());


                // 执行业务逻辑并对客户端进行响应
                String response = process(request);


//              打包一组响应的数据包
//            注意这里要带上对应客户端输入的ip地址和端口号
                DatagramPacket responsePacket = new
                 DatagramPacket(response.getBytes(),0,
                        response.getBytes().length,
                        requestPacket.getSocketAddress());

                // 进行响应回服务器中
                socker.send(responsePacket);

                // 打印日志
                System.out.printf("[ip地址为:%s, %s,端口号为:
                %d, %d 客户端的的需求的为: %s, 服务器的响应为: %s]\n",
                        
                        requestPacket.getAddress(),
                        responsePacket.getAddress(),
                        
                        responsePacket.getPort(),
                        requestPacket.getPort(),
                        
                        request, response);
            }
    }



    // 业务逻辑的方法
    public String process(String request) {
        return request;
    }



    public static void main(String[] args) throws IOException{
        MyServer  myServer = new MyServer(9090);
        myServer.start();
    }
}



在这里插入图片描述

在这里插入图片描述

字典服务器小编在这里只是作为扩展内容, 其实操作远不止这里, 至于字典服务器怎么生成的?

其实很简单, 只是在原来的基础上加入了一个 哈希表 进行返回, 即使不理解的小伙伴也无妨, 重要是理解前面Udp 的回显服务器的 实现原理 即可。

总结

  • Udp与Tcp 协议 : 主要说明的四种 UdpTcp 不同核心特点

  • Udp服务器的实现过程及原理: 先了解 实现回显服务器 Udp 的两个类, 分别是 操作网卡 进行网络通信的
    DatagramSocket 对象 与实现包装数据的 DatagramPacket 数据报。 并实现了
    服务器的代码以及流程讲解。

  • Udp客户端的实现过程及原理:实现了 Udp 的客户端代码 , 并且就客户端的特点进行了流程讲解。

  • 回显服务器的原理剖析及扩展字典服务器功能 : 从 图示的方式 进行理解回显服务器的原理, 并且扩展了 字典服务器
    的内容。

如果觉得小编写的还不错的咱可支持 三连 下 (定有回访哦) , 不妥当的咱请评论区 指正

希望我的文章能给各位宝子们带来哪怕一点点的收获就是 小编创作 的最大 动力 💖 💖 💖

在这里插入图片描述

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

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

相关文章

vue3中ref自动解包

1.模板中使用 ref 类型的数据&#xff0c;会自动解包&#xff0c;注意需要是顶级的ref <template> <!-- 自动解包--><div>{{ name }}</div> </template><script setup> import { ref} from vue const name ref(hello) </script>下…

com.alibaba.fastjson.JSONArray循环引用导致{“$ref“:“$[0]“}

发一个库存~ 在for循环中将对象add到.JSONArray中&#xff0c;arr.toJSONString()&#xff0c;输出的结果如下&#xff1a; [{"sex":"男","age":"10","name":"张三"},{"$ref":"$[0]"},{&quo…

Java synchronized 原理

Synchronized使用 synchronized关键字可使用在方法上或代码块上表示一段同步代码块&#xff1a; public class SyncTest {public void syncBlock(){synchronized (this){System.out.println("hello block");}}public synchronized void syncMethod(){System.out.pr…

小白入门LLM大模型最牛X教程------上交《动手学大模型应用开发》!

本项目是一个面向小白开发者的大模型应用开发教程&#xff0c;旨在结合个人知识库助手项目&#xff0c;通过一个课程完成大模型开发的重点入门&#xff0c;涵盖了大模型应用开发的方方面面&#xff0c;主要包括&#xff1a; 教程一共有七章内容&#xff1a; 《动手学大模型》…

13.5 告警静默

本节重点介绍 : 静默应用场景页面创建api接口创建查看 静默 作用 先告警后静默&#xff1a;持续发送的告警停止发送先配置静默&#xff1a;上线或者运维操作会导致触发一大波告警&#xff0c;提前创建静默消息。防止告警风暴 静默接口 /api/v2/silences 调用静默的代码 …

Leetcode8.字符串转换整数 -codetop

代码&#xff08;首刷看解析 2024年9月5日&#xff09; class Solution { public:int myAtoi(string str) {unsigned long len str.length();// 去除前导空格int index 0;while (index < len) {if (str[index] ! ) {break;}index;}if (index len) {return 0;}int sign …

idea插件开发之bean复制插件

背景 周末在家无事做&#xff0c;顺手开发了一个之前一直想要做的插件&#xff0c;那就是bean复制插件。 在项目中&#xff0c;由于代码分层设计&#xff0c;对于同样一个数据我们通常会定义不同层的实体&#xff0c;例如xxxEntity、xxxDTO、xxxVO等&#xff0c;这些不同的实…

echarts地图绘制并实现下钻功能

本文参考网址 使用echarts地图需要先准备好echarts地图渲染需要的json数据&#xff0c;数据可以从阿里云地址中下载自己需要的&#xff0c;下载之后直接引入即可使用&#xff0c;本文针对全国地图做一个简单的demo 阿里云界面如图 // 1、准备echarts地图容器<div class&…

如何借助AI快速筛选和整理文献?

AIPaperGPT&#xff0c;论文写作神器~ https://www.aipapergpt.com/ 在撰写毕业论文时&#xff0c;文献综述是必不可少的部分。它不仅为你的研究提供理论背景&#xff0c;还展示了你对研究领域的深入理解。然而&#xff0c;文献综述的撰写过程常常让学生感到头疼&#xff0c;…

基于JAVA+SpringBoot+Vue的大学校园回忆录系统

基于JAVASpringBootVue的大学校园回忆录系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末附源码下载链接&#x1f345; …

ElasticSearch-聚合操作

聚合的分类 aggsMetric Aggregation min, max, avg, sumstats, cardinality Bucket Aggregation terms ordertext -> fielddatarangehistogramtop_hits Pipeline Aggregation min_bucketstats_bucketpercentiles_bucketcumulative_sum 聚合的作用范围 Filter, Post Filter,…

5.1.数据结构-c/c++二叉树详解(上篇)(遍历,几种二叉树)

本章所有代码请见&#xff1a;5.3.数据结构-c/c二叉树代码-CSDN博客 目录 一. 二叉树的基本介绍 1.2 满二叉树 1.3 完全二叉树 1.4 搜索二叉树 1.5 平衡二叉搜索树 二. 二叉树的常用操作 2.1 二叉树的定义 2.2 创建一个新的节点 2.3 构建一颗树 2.5 销毁一棵树 三.…

One-Shot Imitation Learning with Invariance Matching for Robotic Manipulation

发表时间&#xff1a;5 Jun 2024 论文链接&#xff1a;https://readpaper.com/pdf-annotate/note?pdfId2408639872513958656&noteId2408640378699078912 作者单位&#xff1a;Rutgers University Motivation&#xff1a;学习一个通用的policy&#xff0c;可以执行一组不…

Linux学习笔记6 值得一读,Linux(ubuntu)软件管理,搜索下载安装卸载全部搞定!(中)

Linux学习笔记5 值得一读&#xff0c;Linux&#xff08;ubuntu&#xff09;软件管理&#xff0c;搜索下载安装卸载全部搞定&#xff01;(上)-CSDN博客 一、前文回顾 上一篇文章我们了解了软件管理的基本概念和软件管理的几种常用工具。我们了解了软件包是由什么形式存在&#…

srt字幕文件怎么制作?分享几个简单步骤,新手必学

srt字幕文件怎么制作&#xff1f;随着短视频平台的发展&#xff0c;现在很多小伙伴喜欢用视频记录生活&#xff0c;分享美好瞬间。在将视频上传到视频平台的时候&#xff0c;我们需要对视频进行剪辑处理。而字幕的使用对提高视频内容的可理解性与传播性变得愈发重要。srt字幕文…

OpenCV 旋转矩形边界

边界矩形是用最小面积绘制的&#xff0c;所以它也考虑了旋转。使用的函数是**cv.minAreaRect**()。 import cv2 import numpy as npimgcv2.imread(rD:\PythonProject\thunder.jpg) img1cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) print(img.dtype) ret,threshcv2.threshold(img1,1…

基于SpringBoot+Vue的美术馆管理系统(带1w+文档)

基于SpringBootVue的美术馆管理系统(带1w文档) 基于SpringBootVue的美术馆管理系统(带1w文档) 本课题研究和开发美术馆管理系统管理系统&#xff0c;让安装在计算机上的该系统变成管理人员的小帮手&#xff0c;提高美术馆管理系统信息处理速度&#xff0c;规范美术馆管理系统信…

【高等数学学习记录】集合

1 知识点 1.1 集合的概念 集合 指具有某种特定性质的事物的总称。集合的元素 组成集合的事物称为集合的元素&#xff08;简称元&#xff09;。有限集、无限集 含有限个元素的集合&#xff0c;则称为有限集&#xff1b;反之&#xff0c;称为无限集。子集 设 A A A、 B B B是两…

HTTP Cookie 和 session

HTTP Cookie HTTP协议本身是无状态&#xff0c;无连接的。 无状态是指&#xff0c;客户每次发起请求&#xff0c;服务器都不认识客户是谁&#xff0c;它只会根据请求返回对应的资源响应。 无连接不是指TCP的无连接&#xff0c;通常指的是HTTP协议本身不在请求和响应之间维护…

哪款宠物空气净化器能更好的清理浮毛?希喂、352、IAM测评分享

家里这三只可爱的小猫咪&#xff0c;已然成为了我们生活中不可或缺的家庭成员&#xff0c;陪伴我们度过了说长不长说短不短的五年时光。时常庆幸自己当年选择养它们&#xff0c;在我失落的时候总能给我安慰&#xff0c;治愈我多时。 但这个温馨的背后也有一点小烦恼&#xff0…