JavaEE(系列20) -- 网络编程之UDP和TCP套接字

news2024/12/21 19:30:43

目录

1. 网络编程

2. UDP网络编程

2.1 DatagramSocket API

2.2 DatagramPacket API

2.3 基于UDP实现的回显服务器 

2.3.1 UDP服务器设计步骤

2.3.2 服务器代码

2.3.3 客户端代码

2.3.4 基于UDP写一个字典服务器

3. TCP网络编程

3.1 ServerSocketAPI

3.2 SocketAPI

​3.3 基于TCP实现的回显服务器 

3.3.1 TCP服务器实现步骤

3.3.2 TCP服务器代码

3.3.3 TCP客户端代码

3.3.4 TCP实现查词典的服务器 


1. 网络编程

        在网络通信中, 数据的发送是从应用层开始, 一直封装到物理层然后进行发送的, 应用层要将数据交给传输层进行封装; 而接收方拿到数据后是从物理层到应用层进行分用, 传输层要将拿到的数据再分用给应用层进行使用, 网络编程实际操作中最关键的就是我们所能控制的应用层和传输层之间的交互, 而在操作系统中提供了一组API即socket, 用来实现应用层和传输层之间的交互, Java当中把操作系统提供的API进行了进一步封装以便我们进行使用.

系统提供的Socket API 主要是两组:基于TCP协议的API 和 基于UDP协议的API

 TCP和UDP这两者的协议之间差别很大,提供的api也差异很大.下面简要概括主要的区别.

TCPUDP
有连接无连接

可靠传输

不可靠传输
面向字节流面向数据报
全双工全双工

1. 什么是有连接?

        使用TCP协议, 必须是通信双方先建立连接才能进行通信(想象打电话的场景这就是有连接), 而使用UDP协议在无连接的情况下可以进行通信(想象发微信, 短信的场景).连接并不是拿一根绳子,把两个设备绑定到一块,而是一个抽象的连接,可以理解成彼此双方记录了对方的信息.比如结婚领证,两个人在民政局进行登记结婚,然后民政局就会给双方发一个结婚证,结婚证是一式两份,供双方所有,这个就是彼此双方做了一个记录,双方进行了连接.

2. 什么是不可靠性传输?

        可靠与不可靠传输指的不是安全性质, 而是说你发送出数据后, 能不能判断对方已经收到, 如果能够确定对方是否收到则就是可靠传输, 否则就是不可靠传输.UDP进行传输,只会关注发送消息,而不会关注发送的消息有没有进行接收.TCP不仅关注发送消息本身而且关注消息是否发送到达.(但是不是说通过TCP就会百分百将消息送达,也会出现丢包的行为.)

3. 什么是全双工?

        全双工是指一条通信链路, 可以双向传输(同一时间既可以发, 也可以收); 而半双工是一条链路, 只能单向通信.

                

 4. 面向字节流和面向数据报?

        面向字节流就类文件读写数据的操作, 是 “流” 式的; 而面向数据报的话数据传输则是以一个个的 “数据报” 为基本单位(一个数据报可能是若干个字节, 是带有一定的格式的).

2. UDP网络编程

2.1 DatagramSocket API

这里receive方法参数传入的是一个空的对象, receive方法内部会对这个对象进行填充, 从而构造出结果数据, 这个参数也是一个输出型参数.

2.2 DatagramPacket API

第二个是DatagramPacket, 表示一个UDP数据报, 在UDP的服务器和客户端都需要使用到, 接收和发送的数据就是在传输DatagramPacket对象, 这就是体现了UDP面向数据报的特点.

在网络编程中, 一定要注意区分清楚服务器与客户端使用之间使用的五元组, 具体如下:

  • 源IP, 就是发送方IP.
  • 源端口, 发送方端口号, 服务器需要手动指定, 客户端让系统随机分配即可.
  • 目的IP, 接收方IP, 包含在拿到的数据报中, 服务器响应时的目的IP就在客户端发来的数据报中, 客户端发送请求时的目的IP就是服务器的IP.
  • 目的端口, 接收方端口号包含在数据报中, 服务器响应时的目的端口就在客户端发来的数据报中, 客户端发送请求时的目的端口.就是服务器的端口号
  • 协议类型, 如UDP/TCP.

2.3 基于UDP实现的回显服务器 

        正常来说服务器为客户端进行提供服务,客户端向服务器发出请求,服务端根据请求来计算响应,然后将响应发送给客户端,这个过程是正常的一个网络通信,在这里本文省略计算响应的环节,服务器将客户端发送的请求进行返回.这就是一个回显程序.

2.3.1 UDP服务器设计步骤

  • 1. 创建Socket实例对象(DatagramSocket对象),需要指定服务器的端口,因为服务器是被动请求的一段,所以得先知道端口号,才能发出请求.
  • 2. 服务器启动,读取客户端的请求,将数据填充到DatagramPacket对象中,这里的请求是包含着有客户端的地址信息(IP+端口号,通过getSocketAddress获取).
  • 3. 处理客户端请求,计算响应,这里实现的是一个回显程序,直接根据请求返回来客户端的请求即可.
  • 4. 将响应返回给客户端,需要将响应打包成DatagramPacket对象,此处打包的过程跟请求的packet是不一样的,需要指定这个包发送给谁,使用getSocketAddress()进行获取.

2.3.2 服务器代码

package UDP;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

/**
 * Created with IntelliJ IDEA.
 * Description:udp 服务端
 * 过程:1.客户端进行请求(requestPacket),服务端进行接收请求(receive)
 *     2.将请求转换成字符串
 *     3.根据请求进行计算响应(需要返回给客户端的数据)
 *     4.将相应装包成responsePacket(对比requestPacket参数多了一个requestPacket的ip和端口号(responsePacket.getSocketAddress()))
 *     5.将打包好的responsePacket,使用send进行发送(返回给客户端)
 * 1. DatagramSocket是文件(快递小哥)
 * 2. DatagramPacket是需要传输的数据包(快递包裹)
 * User: YAO
 * Date: 2023-05-28
 * Time: 20:12
 */
public class udpServer {
    //1. 先定一个socket对象
    // 通过网络通信必须要有socket对象
    private DatagramSocket socket = null;



    //2. 创建构造方法
    // 绑定一个端口号不一定会成功,有可能被别的应用程序占用
    // 同一个主机,同一个端口,同一时刻,只能被一个进程绑定
    public udpServer(int port) throws SocketException {
        // 构造socket的同时,指定关联/绑定的端口
        socket = new DatagramSocket(port);
    }


    //3. 启动服务器
    public void start() throws IOException {
        System.out.println("服务器启动");
        while (true){
            // 每次循环,要做三件事情:
            //1.读取请求并解析
            DatagramPacket requestPacket = new DatagramPacket(new byte[4096],4096);
            socket.receive(requestPacket);  // 此时的参数为输出型参数,传入一个空的对象,交给receive内部进行填充
            //1.1 当服务器启动,start方法被调用就会直接执行到receive这里,如果客户端还没进行发送消息,服务器就会进如堵塞等待
            //1.2 为了方便处理这个请求,我们将这个请求转换成String类型
//            System.out.println(Arrays.toString(requestPacket.getData()));
            String request = new String(requestPacket.getData(),0,requestPacket.getLength());
            //在这里,使用了String类的构造函数来将字节流转换为字符串。
                // 该构造函数有三个参数:
                // 第一个参数是要转换成字符串的字节数组
                // 第二个参数表示从字节数组中哪个位置开始转换
                // 第三个参数表示要转换多少个字节。
            //2. 根据请求计算响应(此处省略)
            String response = process(request);
            //3. 将结果写会给客户端
            //   3.1 根据response字符串,构造一个返回给客户端的DatagramPacket
            //   3.2 和请求packet是不一样的,此处构造相应的时候,需要指定这个包要发送给谁(客户端ip和端口号)
            //       :使用requestPacket.getSocketAddress() 这个方法包含了ip和端口号
            DatagramPacket responsePacket = new DatagramPacket(response.getBytes(StandardCharsets.UTF_8),
                   response.getBytes().length,requestPacket.getSocketAddress());
            //   3.3 打包完成,进行发送
            socket.send(responsePacket);
            System.out.printf("[%s:%d] req: %s, resp: %s\n", requestPacket.getAddress().toString(),
                    requestPacket.getPort(),request, response);
        }
    }

    //4. 根据请求进行计算响应
    //这是一个回显程序,就是客户端发送什么,服务器会送什么,后续可以根据自己需要指定返回的内容,这个函数在服务器中为一个关键
    public String process(String request) {
        return request;
    }

    public static void main(String[] args) throws IOException {
        udpServer udpServer = new udpServer(9090);
        udpServer.start();
        // 此处socket结束整个main方法结束,整个进程就结束了,所以就不需要进行使用socket.close();
    }
}

2.3.3 客户端代码

package UDP;

import java.io.IOException;
import java.net.*;
import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:udp 客户端
 * User: YAO
 * Date: 2023-05-28
 * Time: 20:13
 */
public class udpClient {
    private DatagramSocket socket = null;
    private final String serverIP;
    private final int serverPort;

    // 客户端,需要知道服务器在哪?(IP和Port)
    public udpClient(String serverIP, int serverPort) throws SocketException {
        // 对于客户端,不需要显示关联的的端口
        // 不代表就是没有端口,而是系统自动分配了一个端口
        socket = new DatagramSocket();
        this.serverPort = serverPort;
        this.serverIP = serverIP;

    }
    public void start() throws IOException {
        while (true){
            // 1. 先从控制台读取一个字符串
            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入:");
            String request = scanner.next();
            // 2. 将字符串构造成UDP packet ,并进行发送
            // 2.1 转换成二进制的字符数组,指定的长度,指定服务器的IP,服务器的端口
            DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,
                    InetAddress.getByName(serverIP),serverPort);
            socket.send(requestPacket);
            // 3. 客户端尝试读取服务返回的响应数据
            DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4096);
            socket.receive(responsePacket);
            // 4. 将响应数据进行转换成字符串
            String response = new String(responsePacket.getData(),0,responsePacket.getLength());
            System.out.printf("req: %s, resp: %s\n",request, response);
        }
    }

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

运行结果:

 接收多个客户端发送的请求

2.3.4 基于UDP写一个字典服务器

         上面实现的回显服务器缺乏业务逻辑, 这里在上面的代码的基础上稍作调整, 实现一个 “查词典” 的服务器(将英文单词翻译成中文解释), 这里其实就很简单了, 对于客户端的代码还可以继续使用, 服务器只需把处理请求部分的代码修改即可, 我们可以继承上面的回显服务器, 重写请求部分的代码, 英语单词和汉语解释可以由一个哈希表实现映射关系, 构成词库, 然后根据请求来获取哈希表中对应的汉语解释即可

package UDP;

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

/**
 * Created with IntelliJ IDEA.
 * Description:构建简单翻译服务器
 * User: YAO
 * Date: 2023-05-29
 * Time: 13:16
 */
public class UdpDictServer extends udpServer{

    // 1.使用Map数据结构存储需要翻译的词
    private Map<String,String> dict = new HashMap<>();

    // 2.帮助父类进行构造方法
    public UdpDictServer(int port) throws SocketException {
        super(port);
        dict.put("dog","小狗");
        dict.put("cat","小猫");
        dict.put("fuck","卧槽");
        // .......可以无限的插入数据,跟有道词典相比,咱们的词典就是小.
    }

    //3.重写process方法,进行根据请求进行计算响应
    @Override  // 1.提高可读性(用来提示这个方法是进行重写分类的)  2.校验,编译器进行检查
    public String process(String request){
        return dict.getOrDefault(request,"该单词没有查到");
    }

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

3. TCP网络编程

        TCP相比于UDP有很大的不同, TCP的话首先需要通信双方成功建立连接然后才可以进行通信, TCP进行网络编程的方式和文件读写中的字节流类似, 是字节为单位的流式传输,

        对于TCP的套接字, Java提供了两个类来进行数据的传输, 一个是ServerSocket, 是专门给服务器使用的Socket对象, 用来让服务器接收客户端的连接;第二个是Socket, 这个类在客户端和服务器都会使用, 进行服务器与客户端之间的数据传输通信, TCP的传输可以类比打电话的场景, 客户端发送请求后, 服务器调用ServerSocket类的accept方法来 “建立连接” (接通电话), 建立连接后两端就可以进行通信了, Socket可以获取到文件(网卡)的输入输出流对象, 然后就可以流对象进行文件(网卡)读写了, 体现了TCP面向字节流, 全双工的特点.

3.1 ServerSocketAPI

3.2 SocketAPI

3.3 基于TCP实现的回显服务器 

3.3.1 TCP服务器实现步骤

1. 创建ServerSocket实例对象,需要指定服务器的端口

2. 启动服务器,使用accept方法和客户端进行连接,如果没有客户端进行连接,此时的accept就会进入堵塞等待

3. 接受客户端发送的请求(通过Socket获取输入流InputStream流对象来读取请求)

4. 处理客户端请求进行计算响应

5. 将响应通过客户端(通过Socket获取到OutputStream流对象发送响应)

3.3.2 TCP服务器代码

package TCP;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: YAO
 * Date: 2023-05-31
 * Time: 15:09
 */
public class tcpServerFinal {
    private ServerSocket socket = null;
    public tcpServerFinal(int port) throws IOException {
        socket = new ServerSocket(port);
    }
    public void start() throws IOException {
        System.out.println("服务器启动");
        // 创建线程池用来使用多线程进行处理多个客户端
        ExecutorService pool = Executors.newCachedThreadPool();
        while (true){
            // 接收客户端的连接
            Socket clientSocket  = socket.accept();
            pool.submit(new Runnable() {
                @Override
                public void run() {
                    // 处理客户端的连接
                    processConnection(clientSocket );
                }
            });
        }
    }

    private void processConnection(Socket clientSocket ) {
        System.out.printf("[%s:%d]客户端上线!\n",clientSocket.getInetAddress(),clientSocket.getPort());
        try(InputStream inputStream = clientSocket.getInputStream();
            OutputStream outputStream = clientSocket.getOutputStream()){
            // 将字节流转换成字符流进行操作
            // 1. 输入(接受客户端的输入)
            Scanner scanner = new Scanner(inputStream);
            // 2.输出(写入客户端)
            PrintWriter printWriter = new PrintWriter(outputStream);
            while (true){
                // 1.读取请求
                if(!scanner.hasNext()){
                    System.out.printf("[%s:%d] 客户端下线\n", clientSocket.getInetAddress(),clientSocket.getPort());
                    break;
                }
                // 直接使用scanner进行读取字符串
                String request = scanner.next();
                // 2.根据请求进行计算响应
                String response = process(request);
                // 3.将响应返回给客户端  // 这里println发送是带有换行的
                printWriter.println(response);
                // 由于缓冲区的存在这里我们需要自己手动进行刷新,强行将缓冲池里的东西写入到客户端
                printWriter.flush();
                System.out.printf("[%s:%d] req: %s; resp: %s\n",clientSocket.getInetAddress(),clientSocket.getPort(),request,response);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private String process(String request) {
        return request;
    }

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

    }
}

3.3.3 TCP客户端代码

package TCP;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: YAO
 * Date: 2023-06-01
 * Time: 22:29
 */
public class tcpClientFinal {
    private Socket socket = null;
    public tcpClientFinal(String serverIP, int serverPort) throws IOException {
        socket = new Socket(serverIP,serverPort);
    }
    public void start(){
        Scanner scanner = new Scanner(System.in);
        try(InputStream inputStream = socket.getInputStream();
            OutputStream outputStream = socket.getOutputStream()) {
            PrintWriter printWriter = new PrintWriter(outputStream);
            Scanner scannerFromSocket = new Scanner(inputStream);
            while (true){
                System.out.println("->: ");
                String request = scanner.next();
                printWriter.println(request);
                // 由于缓冲区的存在这里我们需要自己手动进行刷新,强行将缓冲池里的东西写入到服务器
                printWriter.flush();
                String response = scannerFromSocket.next();
                System.out.printf("req: %s; resp: %s\n", request,response);

            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

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

3.3.4 TCP实现查词典的服务器 

package TCP;

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

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: YAO
 * Date: 2023-06-05
 * Time: 15:11
 */
public class tcpServerDict extends tcpServerFinal{
    Map<String,String> dict = new HashMap<>();
    public tcpServerDict(int port) throws IOException {
        super(port);
        dict.put("cat", "小猫");
        dict.put("dog", "小狗");
        dict.put("bird", "小鸟");
    }
    @Override
    public String process(String request){
        return dict.getOrDefault(request,"当前单词没有查到结果");
    }

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

 

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

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

相关文章

如何不出国一年内拿到加拿大女王大学金融硕士学位证书?

作为加拿大最好的公立大学之一&#xff0c;QueensUniversity位于安大略省的金斯顿市。最近&#xff0c;它在QS全球大学排名中跻身第209位&#xff0c;同时在加拿大的综合排名中名列第7位。这表明女王大学在学术研究和教育方面都有着出色的表现。Queens University坐落于安大略省…

分布式光伏发电远程监控系统

分布式光伏发电远程监控系统 项目背景 新能源、可再生能源接入电网是智能电网建设的重要组成&#xff0c;也是能源互联网发展的基础。近年来&#xff0c;太阳能光伏发电技术快速发展&#xff0c;光伏发电并网对配电网的影响也不断加深。电网调度人员需要人工参与光伏发电站的发…

RK3588+FPGA+Cameralink高速相机解决方案

1. 视频接入&#xff0c;其中可见使用LVDS&#xff0c;红外使用cameralink 2. H264低倍率压缩编码本地存储 3. H264压缩使用同步422接口或者网口UDP协议输出实时码流 4. 使用串口进行通讯&#xff0c;进行类似于可见、红外或者激光器或者地面控制软件等之间的通讯 5. 使用网…

SpringBoot3-基础配置和多环境开发

1. 配置文件格式 提供三种属性配置方式&#xff0c;当三个配置文件都有&#xff0c;加载顺序从前至后 示例第二种&#xff08;主要也是用这个&#xff09;&#xff1a; 2. yaml格式 3. yaml读取数据格式的三种方式 第一种&#xff0c;使用Value读取单一属性数据 Value("${…

基于redis实现消息队列(更推荐使用专业的mq)

目录 利用redis实现消息队列&#xff08;基于list&#xff0c;点对点模型&#xff09;——lpush存放队列&#xff08;lpush 队列名 队列内容&#xff08;可一次存放多个内容&#xff0c;用空格隔开&#xff09;&#xff09; brpop取队列&#xff08;brpop 队列名 等待时间单位秒…

机器视觉日常习题(更新中。。。)

目录 第二讲 图像处理概述 第二讲 图像处理概述 几何变换&#xff1a;又称为图像空间变换&#xff0c;它将一幅图像中的坐标位置映射到另一幅图像中的新坐标位置。图像分割&#xff1a;把图像分成各具特色的区域并提取感兴趣目标的技术和过程。图像边缘&#xff1a; 平滑&#…

【深入浅出 Spring Security(六)】一文搞懂密码的加密和比对

Spring Security 中的密码加密 一、PasswordEncoder 详解常见的实现类&#xff08;了解&#xff09;DelegatingPasswordEncoder源码分析DelegatingPasswordEncoder 在哪实例化的&#xff1f; 二、自定义加密自定义方式一&#xff1a;使用{id}的形式自定义方式二&#xff1a;向S…

程序员失业转行送外卖,晒出当天收入,还以为看错了!

在程序员的共识中&#xff0c;30岁之前自己是很受企业欢迎的&#xff0c;有经验有技术&#xff0c;能够为公司创造足够多的价值。 但是一旦超过了35岁&#xff0c;如果没有做到架构师或者成为管理人员&#xff0c;那很可能是连工作都找不到的。而且这个年龄的程序员还要面临着…

700MHz设备对广播电视信号的干扰有哪些?

700MHz&#xff0c;由于其较长的波长&#xff0c;良好的传播与覆盖特性&#xff0c;不仅一直被多国用作广播电视信号频率&#xff0c;4G LTE和5G NR也同样看好这一频段&#xff0c;并在此频段上进行了相应的部署和规划。目前已经有超过45个国家和地区&#xff0c;将700MHz频段部…

【网络安全】企业应急响应基础技能

windows 任务计划列表 1. 计算机管理窗口,选择 系统工具 中 任务计划程序 中的 任务计划程序库选项 可以查看任务计划的名称,状态,触发器等详细信息 2.powershell中输入get-scheduledtask 可以查看当前系统所有任务计划信息 任务路径,名称,状态等详细信息 3.命令行中输入s…

C++11:右值引用,实现移动语义和完美转发

目录 1、右值引用 2、移动语义&#xff08;std::move&#xff09; 3、完美转发&#xff08;std::forward&#xff09; 1、右值引用 右值引用&#xff08;Rvalue reference&#xff09;是C11引入的一个新特性&#xff0c;它是一种新的引用类型&#xff0c;用于表示将要被移动…

5个小时,搭出2套应用,这一低代码平台很强劲!

现代管理学之父德鲁克提及创新本质时&#xff0c;说了两点&#xff1a; 一是让昂贵的东西变得便宜&#xff0c;老百姓能用&#xff1b;二是让高门槛东西变得低门槛&#xff0c;普通人可用。 而低代码正符合这两个条件。 一、背景 所谓低代码&#xff0c;是一种软件开发方法&…

常用的LED显示屏驱动芯片和控制系统

常用的LED显示屏驱动芯片包括以下几种&#xff1a; TPIC6B595&#xff1a;这是一种串行输入、并行输出的LED显示屏驱动芯片&#xff0c;适用于驱动7段数码管等简单的LED显示屏。 MAX7219/MAX7221&#xff1a;这是一种常用的LED显示屏驱动器&#xff0c;可驱动8x8点阵LED显示屏。…

npm 发布新包或者新模块后,无法下载最新版本,如何解决?

目录 1、方法一&#xff1a;在npm官网搜索对应的模块&#xff0c;看看是否有最新版本的存在&#xff1f; 2、方法二&#xff1a;排查本地使用的是什么镜像&#xff1f; 3、方法三&#xff1a;将淘宝镜像切换成npm镜像 1、方法一&#xff1a;在npm官网搜索对应的模块&#xf…

运维小白必学篇之基础篇第十四集:DHCP中继实验

DHCP中继实验 目录 服务器端&#xff1a;&#xff08;vmware5&#xff09; 中继器端&#xff1a;(双网卡ens33、vmware5&#xff1b;ens36、vmware6&#xff09; 客户端&#xff1a;&#xff08;vmware6&#xff09; 实验作业&#xff08;主机名为自己的名字&#xff09;&a…

WebGIS学习-01-GIS基础概念与Mapbox基础

1.地图数据来源 1.栅格数据&#xff1a; -.jpg&#xff0c;.png等图片数据&#xff1b; -卫星等拍摄的影像&#xff1b;.tiff 2.矢量数据&#xff1a; -geojson的数据&#xff0c;多用于绘制边界 -放大缩小都不会失真&#xff0c;且高度支持手绘 2.网页是如何渲染地图数据的 …

什么是压力测试?如何进行Jmeter压力测试

一、什么是压力测试 软件测试中&#xff1a;压力测试&#xff08;Stress Test&#xff09;&#xff0c;也称为强度测试、负载测试。压力测试是模拟实际应用的软硬件环境及用户使用过程的系统负荷&#xff0c;长时间或超大负荷地运行测试软件&#xff0c;来测试被测系统的性能、…

深度学习-调参技巧总结

针对CNN优化的总结 使用没有 batchnorm 的 ELU 非线性或者有 batchnorm 的 ReLU。用类似1*1的网络结构预训练RGB数据&#xff0c; 能得到更好的效果。使用线性学习率衰退策略。使用平均和最大池化层的和。使用大约 128&#xff08;0.005&#xff09; 到 256 &#xff08;0.01&a…

5.1 - Web漏洞 - XSS漏洞详解

「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 XSS漏洞 一、什么是XSS&#xff1f;二、XSS概述三、靶场练习四、XSS使用步骤五、XSS攻击类…

el-table动态表头数据渲染

desc&#xff1a;el-table的数据是后端动态返回的&#xff0c;包括表头的情况下如何进行渲染 // 第一页的数据 {"code": 1,"message": "查询成功","data": {"current": 1,"size": 10,"total": 41,"…