17_网络编程

news2024/11/20 12:42:12

文章目录

  • 网络数据传输的基本原理
  • UDP
    • 发送端步骤
    • 接收端步骤
    • DatagramSocket
    • DatagramPacket
    • 举例
      • 版本1:发送端发送消息,接收端接收并打印
      • 版本2:创建一个NetworkUtils工具类优化版本1
      • 版本3:发送端接收端相互发送
      • 版本4:使用多线程
  • TCP
    • 客户端步骤
    • 服务端步骤
    • Socket
    • ServerSocket
    • 举例
      • 版本1:客户端发送消息,服务端接收并打印
      • 版本2:多个客户端发送,服务端接收(多线程处理)
      • 版本3:客户端发送对象(序列化),服务端接收
      • 版本4:客户端上传文件到服务端

网络数据传输的基本原理

在这里插入图片描述

  • ip地址
    • 唯一确定目的主机
  • port 端口号
    • 唯一确定进程
  • 协议
    • UDP协议:无连接的不可靠的协议
    • TCP协议:面向连接的可靠的协议

UDP

在这里插入图片描述

发送端步骤

  1. 创建发送端的socket对象
  2. 把要发送的数据封装成数据报包
  3. send方法发送数据报包
  4. 释放资源close

接收端步骤

  1. 创建接收端的socket对象
  2. 创建用于接收的数据报包
  3. receive方法接收数据
  4. 解析数据报包
  5. 释放资源close

DatagramSocket

类表示用来发送和接收数据报包的套接字

构造方法


DatagramSocket(int port)     //  创建数据报套接字并将其绑定到本地主机上的指定端口。

成员方法
在这里插入图片描述

DatagramPacket

此类表示数据报包

构造方法


1. 用于发送的
DatagramPacket(byte[] buf,  int offset, int length, InetAddress address, int port)      
// 构造数据报包,用来将长度为 length 偏移量为 offset  的包发送到指定主机上的指定端口号
// InetAddress address ---> ip值

2. 用于接受的
DatagramPacket(byte[] buf,  int offset, int length)      
// 构造DatagramPacket,用来接收长度为 length 的包,在缓冲区中指定了偏移量。

成员方法

在这里插入图片描述

举例

版本1:发送端发送消息,接收端接收并打印


// 发送端sender
public class Sender {
    public static void main(String[] args) throws IOException {

        //   1. 创建发送端的socket对象
        DatagramSocket datagramSocket = new DatagramSocket(8888);

        //   2. 把要发送的数据封装成数据报包
        String s = "hello";
        // DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
        // 构造数据报包,用来将长度为 length 偏移量为 offset  的包发送到指定主机上的指定端口号
        byte[] bytes = s.getBytes();
        InetAddress targetIP = InetAddress.getByName("127.0.0.1");
        int port = 9999;
        DatagramPacket sendPacket =
                new DatagramPacket(bytes, 0, bytes.length, targetIP, port);

        //   3. send方法发送数据报包
        datagramSocket.send(sendPacket);

        //   4. 释放资源close
        datagramSocket.close();
    }
}


———————————————————————————————————————————————————————————————————————————————————————————

// 接收端receiver
public class Receiver {

    public static void main(String[] args) throws IOException {
        // 1. 创建接收端的socket对象
        DatagramSocket datagramSocket = new DatagramSocket(9999);

        // 2. 创建用于接收的数据报包
        // DatagramPacket(byte[] buf,  int offset, int length)
        // 构造DatagramPacket,用来接收长度为 length 的包,在缓冲区中指定了偏移量。
        byte[] bytes = new byte[1024];
        DatagramPacket receivePacket = new DatagramPacket(bytes, 0, bytes.length);

        // 3. receive方法接收数据
        System.out.println("receiver before");
        datagramSocket.receive(receivePacket);
        System.out.println("receiver after");

        // 4. 解析数据报包
        byte[] data = receivePacket.getData();
        int length = receivePacket.getLength();
        int offset = receivePacket.getOffset();
        System.out.println(new String(data, offset, length));

        // 5. 释放资源close
        datagramSocket.close();

    }
}


版本2:创建一个NetworkUtils工具类优化版本1


NetworkUtil.java

public class NetworkUtils {

    // 提供一个获取发送数据报包的方法
    public static DatagramPacket getSendPacket(String msg, String ip, int port) 
    throws UnknownHostException {
        // 把数据封装到包里
        byte[] bytes = msg.getBytes();
        InetAddress targetIP = InetAddress.getByName(ip);
        DatagramPacket sendPacket = 
                new DatagramPacket(bytes, 0, bytes.length, targetIP, port);
        return sendPacket;
    }

    // 提供一个获取接受数据报包的方法
    public static DatagramPacket getReceivePacket() {
        // 创建接收数据报的包
        byte[] bytes = new byte[1024];
        DatagramPacket receivePacket = 
                new DatagramPacket(bytes, 0, bytes.length);
        return receivePacket;
    }

    // 提供一个解析数据报包的方法
    public static String parseMsg(DatagramPacket receivePacket) {
        byte[] bytes = receivePacket.getData();
        int length = receivePacket.getLength();
        int offset = receivePacket.getOffset();
        return new String(bytes,offset,length);
    }
}


————————————————————————————————————————————————————————————————————————————————————————————

// sender 发送端
public class Sender {
    public static void main(String[] args) throws IOException {
        DatagramSocket datagramSocket = new DatagramSocket(8888);

        String s = "hello hi";
        DatagramPacket sendPacket = NetworkUtils.getSendPacket(s, "127.0.0.1", 9999);

        datagramSocket.send(sendPacket);

        datagramSocket.close();
    }
}


————————————————————————————————————————————————————————————————————————————————————————————

// 接收端receiver

public class Receiver {
    public static void main(String[] args) throws IOException {
        DatagramSocket datagramSocket = new DatagramSocket(9999);

        DatagramPacket receivePacket = NetworkUtils.getReceivePacket();

        datagramSocket.receive(receivePacket);

        String s = NetworkUtils.parseMsg(receivePacket);
        System.out.println(s);

        datagramSocket.close();
    }
}

版本3:发送端接收端相互发送


// 发送端sender
public class Sender {
    public static void main(String[] args) throws IOException {

        // 1. 创建发送端的socket对象
        DatagramSocket datagramSocket = new DatagramSocket(8888);

        // 2. 创建Scannner对象
        Scanner scanner = new Scanner(System.in);

        // while循环
        while (true) {
            // 3. 发送逻辑
            // 键盘接收数据
            String s = scanner.nextLine();

            // 把数据封装成数据包
            DatagramPacket sendPacket = NetworkUtils.getSendPacket(s, "127.0.0.1", 9999);

            // send
            datagramSocket.send(sendPacket);

            // 4. 接受逻辑
            // 创建用于接受的数据报包
            DatagramPacket receivePacket = NetworkUtils.getReceivePacket();

            // receive方法接收
            datagramSocket.receive(receivePacket);

            // 解析
            String s1 = NetworkUtils.parseMsg(receivePacket);
            System.out.println("接收到了" + receivePacket.getSocketAddress() + "的消息" + s1);
        }
    }
}



// 接收端 receiver
public class Receiver {
    public static void main(String[] args) throws IOException {
        // 创建接收端的Socket对象
        DatagramSocket datagramSocket = new DatagramSocket(9999);

        // 创建Scanner对象
        Scanner scanner = new Scanner(System.in);

        // while循环
        while (true) {
            // 接受逻辑
            // 创建用于接受的数据报包
            DatagramPacket receivePacket = NetworkUtils.getReceivePacket();
            // receive接受
            datagramSocket.receive(receivePacket);
            // parse解析
            String msg = NetworkUtils.parseMsg(receivePacket);
            System.out.println("接收到了" + receivePacket.getSocketAddress() + "的消息" + msg);

            // 发送逻辑
            // 键盘接收数据
            String s = scanner.nextLine();

            // 把数据封装成包
            DatagramPacket sendPacket = NetworkUtils.getSendPacket(s, "127.0.0.1", 8888);

            // send
            datagramSocket.send(sendPacket);

        }
    }
}

版本4:使用多线程

在这里插入图片描述

  • 定义发送任务 SendTask 专门用来发送消息
  • 定义接收任务 receiveTask 专门用来接收消息

eg:


SendTask:
public class SenderTask implements Runnable {

    // DatagramSocket datagramSocket
    DatagramSocket datagramSocket;

    // String ip
    String ip;

    // int port
    int port;

    public SenderTask(DatagramSocket datagramSocket, String ip, int port) {
        this.datagramSocket = datagramSocket;
        this.ip = ip;
        this.port = port;
    }

    @Override
    public void run() {
        // 创建Scanner对象
        Scanner scanner = new Scanner(System.in);

        // while
        while(true){
            // 键盘输入消息
            String s = scanner.nextLine();

            // 把消息封装成数据报包
            try {
                DatagramPacket sendPacket = NetworkUtils.getSendPacket(s, ip, port);
                // send
                datagramSocket.send(sendPacket);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}



ReceiveTask:
public class ReceiveTask implements Runnable{

    // 成员变量
    DatagramSocket datagramSocket;

    public ReceiveTask(DatagramSocket datagramSocket) {
        this.datagramSocket = datagramSocket;
    }

    @Override
    public void run() {
        // 只是接收数据
        while(true){
            // 创建用于接收的数据报包
            DatagramPacket receivePacket = NetworkUtils.getReceivePacket();

            // receive接收
            try {
                datagramSocket.receive(receivePacket);
                // 解析
                String s = NetworkUtils.parseMsg(receivePacket);
                // 打印
                System.out.println("s = " + s);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}



OnePerson:
public class OnePerson {
    public static void main(String[] args) throws IOException {
        // 创建DatagramSocket对象
        DatagramSocket datagramSocket = new DatagramSocket(8888);

        // 创建发送线程 接收线程并启动
        new Thread(new SenderTask(datagramSocket,"127.0.0.1",9999)).start();

        // 创建接收线程
        new Thread(new ReceiveTask(datagramSocket)).start();
    }
}



AnotherPersonpublic class AnotherPerson {
    public static void main(String[] args) throws IOException {
        // 创建DatagramSocket对象
        DatagramSocket datagramSocket = new DatagramSocket(9999);

        // 创建发送线程 接收线程并启动
        new Thread(new SenderTask(datagramSocket, "127.0.0.1", 8888)).start();

        // 创建接收线程
        new Thread(new ReceiveTask(datagramSocket)).start();
    }
}


TCP

在这里插入图片描述

客户端步骤

  1. 创建客户端Socket对象(Socket)

  2. 从socket中获取输入输出流

  3. 利用输出输出流进行读写操作

  4. 释放资源close

服务端步骤

  1. 创建服务端的socket对象(ServerSocket)

  2. 通过accept建立连接, 得到socket对象

  3. 从socket中得到输入输出流

  4. 利用输入输出流进行读写操作

  5. 释放资源

Socket

此类实现客户端套接字

构造方法


Socket(String host,  int port)       
// 创建一个流套接字并将其连接到指定主机上的指定端口号。

:这里的host指的是目的主机的指定端口

成员方法

  • 在这里插入图片描述
  • 在这里插入图片描述

ServerSocket

此类实现服务器套接字

构造方法


ServerSocket(int port)        
// 创建绑定到特定端口的服务器套接字。

成员方法

  • 在这里插入图片描述

举例

版本1:客户端发送消息,服务端接收并打印

注意事项

  • 先启动服务端,后启动客户端
  • 端口号不能重复,如果重复占用的话,换一个端口号

eg:


客户端Clientpublic class Client {
    public static void main(String[] args) throws IOException {
        // 1. 创建客户端Socket对象
        // Socket(String host,  int port)
        Socket socket = new Socket("127.0.0.1", 9999);

        // 2. 从socket中获取输入输出流
        OutputStream out = socket.getOutputStream();

        // 3. 利用输出输出流进行读写操作
        out.write("hello".getBytes());

        // 4. 释放资源close
        socket.close();
    }
}



服务端Serverpublic class Server {
    public static void main(String[] args) throws IOException {
        // 1. 创建服务端的socket对象(ServerSocket)
        // ServerSocket(int port)
        ServerSocket serverSocket = new ServerSocket(9999);

        // 2. 通过accept建立连接, 得到socket对象
        Socket socket = serverSocket.accept();

        // 3. 从socket中得到输入输出流
        InputStream inputStream = socket.getInputStream();

        // 4. 利用输入输出流进行读写操作
        byte[] bytes = new byte[1024];
        int readCount = inputStream.read(bytes);
        System.out.println(new String(bytes, 0, readCount));

        // 5. 释放资源
        serverSocket.close();
        socket.close();

    }
}

版本2:多个客户端发送,服务端接收(多线程处理)

eg:


客户端Clientpublic class Client {
    public static void main(String[] args) throws IOException {
        // 创建客户端的socket对象
        Socket socket = new Socket("127.0.0.1",9999);
        // 创建scanner对象
        Scanner scanner = new Scanner(System.in);

        // while循环
        while(true){
            String s = scanner.nextLine();
            // 从socket对象中获取输入输出流
            // 字节流
            OutputStream out = socket.getOutputStream();

            // 转换成字符流
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(out);
            // write
//            out.write(s.getBytes());

            outputStreamWriter.write(s);

            // flush
            outputStreamWriter.flush();
        }
    }
}


服务端Serverpublic class Server {
    public static void main(String[] args) throws IOException {
        // 创建服务端的socket对象
        ServerSocket serverSocket = new ServerSocket(9999);

        // 创建线程池
        ExecutorService pool = Executors.newFixedThreadPool(2);

        // while循环
        while (true){
            // 通过accept方法建立连接
            Socket socket = serverSocket.accept();

            // 向线程池中提交任务
            pool.submit(new ConnectTask(socket));

            // 使用多线程
            // new Thread(new ConnectTask(socket)).start();
        }
    }
}

// 多线程改进
class ConnectTask implements Runnable{

    // 定义成员变量
    Socket socket;

    public ConnectTask(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        // 读取数据

        while (true){
            try {
                InputStream in = socket.getInputStream();
                byte[] bytes = new byte[1024];
                int readCount = in.read(bytes);
                String s = new String(bytes, 0, readCount);
                System.out.println("接收到了来自" + socket.getLocalAddress()
                        + "端口号是:" + socket.getPort()
                        + "线程名是:" + Thread.currentThread().getName()
                        + ",内容是:" + s);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

版本3:客户端发送对象(序列化),服务端接收

ObjectOutputStream 将 Java 对象的基本数据类型和图形写入 OutputStream
可以使用 ObjectInputStream 读取(重构)对象。通过在流中使用文件可以实现对象的持久存储如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象

eg:


客户端Clientpublic class Client {
    public static void main(String[] args) throws IOException {
        // 创建客户端socket对象
        Socket socket = new Socket("127.0.0.1", 12300);

        // 从socket中获取输出流
        OutputStream out = socket.getOutputStream();

        // 把输出流进行包装,包装成序列化流
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);

        // 创建学生对象
        Student student = new Student("zs", 20);

        // writeObject
        objectOutputStream.writeObject(student);

        // close
        objectOutputStream.close();
        socket.close();
    }
}



服务端Serverpublic class Server {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        // 创建客户端的socket对象
        ServerSocket serverSocket = new ServerSocket(12300);

        // accept方法建立连接,得到socket对象
        Socket socket = serverSocket.accept();

        // 得到输入流
        InputStream in = socket.getInputStream();

        // 把输入流进行包装 ObjectInputStream
        ObjectInputStream objectInputStream = new ObjectInputStream(in);

        // readObject
        Object o = objectInputStream.readObject();

        // 打印
        System.out.println(o);

        // close
        objectInputStream.close();
        socket.close();
        serverSocket.close();
    }
}


版本4:客户端上传文件到服务端

在这里插入图片描述

eg:


客户端Client// 客户端上传文件到服务端
public class Client {
    public static void main(String[] args) throws IOException {
        // 创建客户端的socket对象
        Socket socket = new Socket("127.0.0.1", 12345);

        // 创建自己的输入流对象
        FileInputStream fileInputStream = 
        	  new FileInputStream("D:\\Java_test\\testPhoto.jpg");

        // 通过自己的输入流读取文件信息
        OutputStream outputStream = socket.getOutputStream();

        // 通过socket获取输出流对象
        int readCount;
        byte[] bytes = new byte[1024];
        while ((readCount = fileInputStream.read(bytes)) != -1) {
            // 边读边写
            outputStream.write(bytes, 0, readCount);
        }

        // 释放资源
        fileInputStream.close();
        outputStream.close();
        socket.close();
    }
}



服务端Serverpublic class Server {
    public static void main(String[] args) throws IOException {
        // 创建服务端的socket对象
        ServerSocket serverSocket = new ServerSocket(12345);

        // 创建自己的输出流对象
        FileOutputStream fileOutputStream = 
                new FileOutputStream("D:\\darkNight.jpg");

        // accept方法建立连接 得到socket对象
        Socket socket = serverSocket.accept();

        // 从socket中获取输入流
        InputStream in = socket.getInputStream();

        // 边读边写
        int readCount;
        byte[] bytes = new byte[1024];
        while ((readCount = in.read(bytes)) != -1) {
            fileOutputStream.write(bytes, 0, readCount);
        }

        // 释放
        serverSocket.close();
        socket.close();
        fileOutputStream.close();
        in.close();
    }
}

  • 在这里插入图片描述
    Socket的半关闭

版本4plus:

eg:


客户端Clientpublic class Server {
    public static void main(String[] args) throws IOException {
        // 创建服务端的socket对象
        ServerSocket serverSocket = new ServerSocket(12345);

        // 创建自己的输出流对象
        FileOutputStream fileOutputStream =
                new FileOutputStream("D:\\darkNight.jpg");

        // accept方法建立连接 得到socket对象
        Socket socket = serverSocket.accept();

        // 从socket中获取输入流
        InputStream in = socket.getInputStream();

        // 边读边写
        int readCount;
        byte[] bytes = new byte[1024];
        while ((readCount = in.read(bytes)) != -1) {
            fileOutputStream.write(bytes, 0, readCount);
        }

        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("文件上传成功".getBytes());

        // 释放
        serverSocket.close();
        socket.close();
        fileOutputStream.close();
        in.close();
    }
}



服务端Serverpublic class Server {
    public static void main(String[] args) throws IOException {
        // 创建服务端的socket对象
        ServerSocket serverSocket = new ServerSocket(12345);

        // 创建自己的输出流对象
        FileOutputStream fileOutputStream =
                new FileOutputStream("D:\\darkNight.jpg");

        // accept方法建立连接 得到socket对象
        Socket socket = serverSocket.accept();

        // 从socket中获取输入流
        InputStream in = socket.getInputStream();

        // 边读边写
        int readCount;
        byte[] bytes = new byte[1024];
        while ((readCount = in.read(bytes)) != -1) {
            fileOutputStream.write(bytes, 0, readCount);
        }

        OutputStream outputStream = socket.getOutputStream();
        outputStream.write("文件上传成功".getBytes());

        // 释放
        serverSocket.close();
        socket.close();
        fileOutputStream.close();
        in.close();
    }
}


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

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

相关文章

SOLID 原则

单一功能原则 单一功能原则(Single responsibility principle)规定每个类都应该有一个单一的功能,并且该功能应该由这个类完全封装起来。所有它的(这个类的)服务都应该严密的和该功能平行(功能平行&#x…

【GitHub项目推荐--13 个 Python 学习资源】【转载】

近些年,人工智能应用铺天盖地。人脸识别、老照片复活、换脸等应用都得益于人工智能算法。 许多人工智能算法封装的框架基于 Python 语言,这也导致了 Python 的热度只增不减。 Python 简单易学,根据 2020 年 StackOverflow 开发者调查报告显…

Spring boot - Task Execution and Scheduling @Async

SpringBoot的任务执行器 Spring Boot通过auto-configuration机制自动创建了任务执行器Task Execution,因此在SpringBoot项目中,你不需要任何配置、也不需要自己创建Task Execution就可以直接使用它。 Spring Boot通过auto-configuration机制创建的任务…

学会这个技巧,制作电子杂志SOEASY

​电子杂志是一种非常流行的传播方式,它能够以更加生动、直观的方式展示你的品牌和产品。通过电子杂志,你可以将文字、图片、视频等多种元素有机地结合起来,创造出令人难忘的视觉效果。 如果你想制作一本电子杂志,但不知道从何入…

Apache POI 导出Excel报表

大家好我是苏麟 , 今天聊聊Apache POI . Apache POI 介绍 Apache POI 是一个处理Miscrosoft Office各种文件格式的开源项目。简单来说就是,我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作。 一般情况下,POI 都是用于操作 E…

相对原子质量的定义是什么,为什么要引入相对原子质量,相对原子质量是一个比值吗,单位是1吗?和原子实际质量的关系。

问题描述:相对原子质量的定义是什么,为什么要引入相对原子质量,相对原子质量是一个比值吗,单位是1吗?和原子实际质量的关系。 问题解答: 定义:相对原子质量是指元素的一个原子质量相对于碳-12…

街机模拟游戏逆向工程(HACKROM)教程:[1]数据的存储与读取

简介 在计算机中,数据存储的介质一直在变化,从最早的穿孔纸带,到现在的固态硬盘。但存储的原理是一直没有变化的,在计算机中,我们所存储的数据,一直都是以二进制的形式被存储存在不同的介质中。 计算机用…

数据在AI任务中的决定性作用:以图像分类为例

人工智能的学习之路非常漫长,不少人因为学习路线不对或者学习内容不够专业而举步难行。不过别担心,我为大家整理了一份600多G的学习资源,基本上涵盖了人工智能学习的所有内容。点击下方链接,0元进群领取学习资源,让你的学习之路更加顺畅!记得…

数据结构——顺序二叉树——堆

1.树的相关概念 在介绍二叉树之前,我们首先要明确树是什么。 树用我们的通常认识来判断应该是一种植物,从根向上生长,分出许多的树枝并长出叶子。对于数据结构中的树而言,其结构也正是从树的特征中剥离出来的。树结构是一种非线性…

求斐波那契数列矩阵乘法的方法

斐波那契数列 先来简单介绍一下斐波那契数列: 斐波那契数列是指这样一个数列:1,1,2,3,5,8,13,21,34,55,89……这个数列从第3项开始 &…

Scratch优秀作品飞翔小鸟

程序说明:在无尽的划痕堆中飞驰而过随着你越来越多地飞进迷宫般的街区,平台变得越来越难。 演示视频 scratch飞翔小鸟 其实这就是一个类似像素小鸟的程序,只不过水管角色就地取材,使用scratch里面的积木图片拼成了水管&#xff0…

【算法】了解哈希表/思想 并用哈希解算法题(C++)

文章目录 基本了解解题1.两数之和面试题01.02.判定是否互为字符重排217.存在重复元素219.存在重复元素II49.字母异位词分组 基本了解 哈希表是什么? 一种数据结构,用于存储元素。 有什么用? 用于快速查找元素 与 插入 何时用哈希表&…

代码随想录 Leetcode160. 相交链表

题目: 代码(首刷看解析 2024年1月13日): class Solution { public:ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {ListNode *A headA, *B headB;while (A ! B) {A A ! nullptr ? A->next : headB;B B ! nullpt…

Shell编程自动化之Shell数学运算与条件测试

一、Shell数学运算 1.Shell常见的算术运算符号 序号算术运算符号意义1、-、*、/、%加、减、乘、除、取余2**幂运算3、–自增或自减4&&、||、!与、或、非5、!相等、不相等,也可写成6、、-、*、/、%赋值运算符,a1相等于aa1 2.Shell常…

HUAWEI华为MateStation S台式机电脑12代PUC-H7621N,H5621N原装出厂Windows11.22H2系统

链接:https://pan.baidu.com/s/1QtjLyGTwMZgYiBO5bUVPYg?pwd8mx0 提取码:8mx0 原厂WIN11系统自带所有驱动、出厂主题壁纸、系统属性专属联机支持标志、Office办公软件、华为电脑管家等预装程序 文件格式:esd/wim/swm 安装方式&#xf…

高光谱分类论文解读分享之基于形态卷积神经网络的高光谱影像分类

IEEE TGRS 2021:基于形态卷积神经网络的高光谱影像分类 题目 Morphological Convolutional Neural Networks for Hyperspectral Image Classification 作者 Swalpa Kumar Roy; Ranjan Mondal; Mercedes E. Paoletti; Juan M. Haut; Antonio Plaza 关键词 Clas…

Ubuntu下使用Virtual Box中显示没有可用的USB设备

Ubuntu中使用Virtual Box,但是使用到USB时只有USB1.1可以使用,并且提示没有可以使用的USB设备,解决方法如下 下载并安装Vitrual Box提供的功能扩展包 分别点击帮助->关于,查看当前使用的版本进入到Virtual Box官网下载链接根…

LabVIEW在金属铜大气腐蚀预测评价系统中的应用

为了应对电子设备和仪器中金属铜因大气腐蚀带来的挑战,开发一种基于LabVIEW平台的先进预测评价系统。这个系统的设计宗旨是准确预测并评估在不同室内外环境中金属铜的腐蚀状况。我们团队在LabVIEW的强大数据处理和图形化编程支持下,结合实际的大气腐蚀数…

【Java语言基础②】Java基本语法——Java程序基本格式,注释,标识符,常量

通过前面的学习,大家对Java语言有了一个基础认识,但现在还无法使用Java语言编写程序,要熟练使用Java语言编写程序,必须充分掌握Java语言的基础知识。今天咱们就来聊一聊Java的基本语法。 1.java程序的基本格式 Java程序代码必须…

制作docker镜像时,使用copy命令统一文件的不同所属用户

一、背景 在制作docker镜像时,使用COPY命令,可以统一原本不同所属用户的文件为同一个用户root。 我们都知道,linux系统,不同的用户之间的访问是受限的。 整个文件夹的用户通体都是devuser,但是里面的文件却是其他用户…