java之网络编程篇

news2024/11/16 13:51:42

前言

网络编程就是计算机和计算机之间通过网络进行数据传输,下面介绍一些概念和如何实现UDP和TCP两种模式的传输。

一、常见的软件架构C/S和B/S

C/S架构需要一个客户端软件程序+服务器

B/S只需要打开网页+服务器

 C/S架构的优缺点和应用场景

优点:画面可以做的非常精美,用户体验好

缺点:需要开发客户端,也需要开发服务端

           用户需要下载和更新的时候太麻烦

应用场景:适合定制专业化的办公类软件如:IDEA、网游

 B/S架构的优缺点和应用场景

优点:不需要开发客户端,只需要开发服务端

           用户不需要下载,打开浏览器就能使用

缺点:如果应用过大,用户体验受到影响

应用场景:适合移动互联网应用,可以在任何地方随时访问的系统。

二、网络编程三要素(IP、端口号、协议)

1.概述

IP               设备在网络中的地址,是唯一的标识。

端口号        应用程序在设备中唯一的标识。

协议           数据在网络中传输的规则,常见的协议有UDP、TCP、http、https、ftp。

2.详说

IP

全称:Internet Protocol,是互联网协议地址,也称IP地址。

是分配给上网设备的数字标签。

 通俗理解就是,上网设备在网络中的地址,是唯一的

常见的IP分类为 IPv4、IPv6

为解决IPv4的IP不够用的问题,出现了IPv6

IPv4的细节

分类:公网地址(万维网使用)和私有地址(局域网使用)。

           192.168.开头的就是私有址址,范围即为192.168.0.0--192.168.255.255,专门为组织机构内部使用,以此节省IP

三个问

1.IPv6还未普及,现在如何解决IPv4不够的问题?

利用局域网IP解决IP不够的问题

2.特殊的IP是什么?

127.0.0.1(永远表示本机)

3.常见的两个CMD命令

ipconfig:查看本机IP地址

ping:检查网络是否连通

 InetAddress类

 InetAddress类可以获取IP对象,主机名,IP

public class InetAddressTest {
    public static void main(String[] args) throws UnknownHostException {
        //传递电脑的名字或网址都可以获得对应的IP地址
        InetAddress address = InetAddress.getByName("LAPTOP-8DV5B4U6");
        System.out.println(address);

        //获得本机的主机名
        String hostName = address.getHostName();
        System.out.println(hostName);

        //获得本机的IP地址
        String hostAddress = address.getHostAddress();
        System.out.println(hostAddress);
    }
}

 端口号

就是,应用程序在设备中唯一的标识。

端口号:由两个字节表示的整数,取值范围:0~65535

                其中0~1023之间的端口号用于一些知名的网络服务或者应用。

                我们自己使用1024以上的端口号就可以了。

注意:一个端口号只能被一个应用程序使用。

传输的数据只能由电脑绑定的端口号的端口发出和接收

协议

计算机网络中,连接和通信的规则被称为网络通信协议。

下面是传输层的两个协议UDP和TCP

三、UDP 

1.发送数据

步骤

(1)创建发送端的DatagramSocket对象

(2)数据打包(DatagramPacket)

(3)发送数据

(4)释放资源

示例代码

public class SendDataTest {
    public static void main(String[] args) throws IOException {
        //1.创建UDP  socket 即new 一个 DatagramSocket对象
        //细节:
        //绑定端口,以后我们就是通过这个端口往外发送
        //空参:所有可用的端口中随机一个进行使用
        //带参:指定端口进行绑定
        DatagramSocket socket = new DatagramSocket();

        //2.打包数据
        byte[] data = "你好厉害u".getBytes();
        InetAddress address = InetAddress.getByName("127.0.0.1");
        int port = 10086;

        DatagramPacket packet = new DatagramPacket(data, data.length, address, port);

        //3.发送数据
        socket.send(packet);

        //关闭资源
        socket.close();

    }
}

 2.接收数据

步骤

(1)创建接收端的DatagramSocket对象

(2)接收打包好的数据(DatagramPacket)

(3)解析数据包

(4)释放资源

 示例代码

public class ReceiveDataType {
    public static void main(String[] args) throws IOException {
        // 1.创建一个DatagramSocket对象
        //细节:
        //在接收的时候,一定要绑定端口
        //而且绑定的端口一定要跟发送的端口保持一致
        DatagramSocket socket = new DatagramSocket(10086);

        // 2.创建一个DatagramPacket对象接收数据
        byte[] bytes = new byte[1024];
        DatagramPacket packet = new DatagramPacket(bytes,bytes.length);
        //该方法是阻塞的
        //程序执行到这一步的时候,会在这里死等
        //等发送端发送消息
        socket.receive(packet);

        //3.解析数据
        byte[] data = packet.getData();
        int len = packet.getLength();
        String str = new String(data,0,len);
        InetAddress address = packet.getAddress();
        int port = packet.getPort();

        System.out.println("接收到的数据:"+str);
        System.out.println("这数据从"+address+"这台电脑中的"+port+"端口发出");

        //关闭资源
        socket.close();
    }
}

3.聊天室

按照下面的要求实现程序
UDP发送数据:娄数据来自于键盘录入,直到输入的数据是886,发送数据结束
UDP接收数据:因为接收端不知道发送端什么时候停止发送,故采用死循环接收 

发送端代码

public class SendSide {
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket();

        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("请输入要发送的信息:");
            String s = scanner.nextLine();
            if ("886".equals(s)){
                break;
            }
            byte[] data = s.getBytes();
            InetAddress address = InetAddress.getByName("127.0.0.1");
            int port = 10086;
            DatagramPacket packet = new DatagramPacket(data, data.length, address, port);

            socket.send(packet);
        }
        socket.close();
    }
}

 idea里面修改发送代码的运行配置,改为允许多个实例跑

接收端代码

public class ReceiveSide {
    public static void main(String[] args) throws IOException {
        DatagramSocket socket = new DatagramSocket(10086);

        byte[] data = new byte[1024];
        DatagramPacket packet = new DatagramPacket(data, data.length);
        while (true) {
            socket.receive(packet);

            byte[] data1 = packet.getData();
            int length = packet.getLength();
            String str = new String(data1, 0, length);
            SocketAddress socketAddress = packet.getSocketAddress();
            System.out.println("来自:" + socketAddress+"发出的一条信息:" + str );
        }
    }
}

4.三种通信方式(单播、组播、广播) 

单播     上面的代码就是单薄

组播      组播地址:224.0.0.0~239.255.255.255      发送到的数据一组的主机都能收到
                其中224.0.0.0~224.0.0.255为预留的组播地址

广播      广播地址:255.255.255.255                        发送到的数据所有的主机都能收到

(1)组播

发送数据步骤

1.创建MulticastSocket对象

2.创建DatagramPacket对象(这里的目的ip对象要指定组播地址比如224.0.0.1)

3.调用MulticastSocket发送数据方法发送数据

4.释放资源

接收数据步骤

1.创建MulticastSocket对象

2.将当前本机,添加到224.0.0.1的这一组当中

3.创建DatagramPacket对象

4.接收数据

5.解析数据

6.释放资源

实例代码

1.发送端代码

public class SendSide {
    public static void main(String[] args) throws IOException {
        //1.创建UDP  socket 即new 一个 MulticastSocket对象
        MulticastSocket socket = new MulticastSocket();

        //2.打包数据
        byte[] data = "你好厉害u".getBytes();
        //指定接收端的组播ip
        InetAddress address = InetAddress.getByName("224.0.0.1");
        //指定接收端的端口
        int port = 10086;

        DatagramPacket packet = new DatagramPacket(data, data.length, address, port);

        //3.发送数据
        socket.send(packet);

        //关闭资源
        socket.close();
    }
}

2.接收端代码 

public class ReceiveSide {
    public static void main(String[] args) throws IOException {
        // 1.创建一个MulticastSocket对象
        //细节:
        //在接收的时候,一定要绑定端口
        //而且绑定的端口一定要跟发送的端口保持一致
        MulticastSocket socket = new MulticastSocket(10086);

        //2..将当前本机,添加到224.0.0.2的这一组当中
        InetAddress address = InetAddress.getByName("224.0.0.2");
        socket.joinGroup(address);

        // 3.创建一个DatagramPacket对象接收数据
        byte[] bytes = new byte[1024];
        DatagramPacket packet = new DatagramPacket(bytes,bytes.length);
        
        //4.接收数据
        //该方法是阻塞的
        //程序执行到这一步的时候,会在这里死等
        //等发送端发送消息
        socket.receive(packet);

        //5.解析数据
        byte[] data = packet.getData();
        int len = packet.getLength();
        String str = new String(data,0,len);
        InetAddress src = packet.getAddress();
        int port = packet.getPort();

        System.out.println("接收到的数据:"+str);
        System.out.println("这数据从"+src+"这台电脑中的"+port+"端口发出");

        //6.关闭资源
        socket.close();
    }
}

设置接收端的代码的运行设置为允许多个实例运行。 

多次运行接收端的代码,控制台多几个接收端的实例,几个接收实例创建就加入224.0.0.2的一个组播地址的组。只要发送端一发送消息,几个接收端都能收到。 

 (2)广播

这个广播只需要在单播的基础上,修改发送端发送包参数指定的目的ip地址。

修改后的发送端代码如下

发送后,无论是多个单播或组播的接收端都是能接收到的。但是端口号还是要对应。

四、TCP

 1.客户端和服务端的步骤

 

2.实例代码

服务端代码

public class ServerType {
    public static void main(String[] args) throws IOException {
        //1.创建一个服务器ServerSocket
        ServerSocket serverSocket = new ServerSocket(10086);
        //2.监听客户端的连接
        //没有客户端连接,会阻塞在这里
        Socket socket = serverSocket.accept();
        //3.获取输入流
        InputStream inputStream = socket.getInputStream();
        //4.读数据
        int b;
        while ((b = inputStream.read()) != -1) {
            System.out.print((char) b);
        }
        //5.关闭流
        inputStream.close();
        socket.close();
    }
}

客户端代码

public class CilentType {
    public static void main(String[] args) throws IOException {
        //1.创建客户端socket
        Socket socket = new Socket("127.0.0.1", 10086);
        //2.获取输出流
        OutputStream outputStream = socket.getOutputStream();
        //3.写数据
        outputStream.write("我是客户端".getBytes());
        //4.关闭资源
        outputStream.close();
        socket.close();
    }
}

 注意:上面的代码是使用字节流传输数据的,中文的话会乱码

因此需要将字节输入流转换为字符输入流,要修改服务端的代码

修改后的服务端的代码

public class ServerType {
    public static void main(String[] args) throws IOException {
        //1.创建一个服务器ServerSocket
        ServerSocket serverSocket = new ServerSocket(10086);
        //2.监听客户端的连接
        //没有客户端连接,会阻塞在这里
        Socket socket = serverSocket.accept();
        //3.获取输入流
        InputStream inputStream = socket.getInputStream();
        //转换为字符流,避免出现中文乱码
        InputStreamReader isr = new InputStreamReader(inputStream);
        //4.读数据
        int b;
        while ((b = isr.read()) != -1) {
            System.out.print((char) b);
        }
        //5.关闭流
        inputStream.close();
        socket.close();
    }
}

运行结果正常 

3.三次握手和四次挥手

(1)三次握手

(2)四次挥手

五、Demo

1.Demo1 多发多收

 客户端代码

public class Client {
    public static void main(String[] args) throws IOException {
        //1.创建Socket对象并连接服务端
        Socket socket = new Socket("127.0.0.1", 10086);

        Scanner sr = new Scanner(System.in);
        //2.获取输出流,发送数据
        OutputStream outputStream = socket.getOutputStream();
        while (true) {
            System.out.println("请输入要发送的数据:");
            String str = sr.nextLine()+"\r\n";
            if ("886".equals(str)){
                break;
            }
            outputStream.write(str.getBytes());
        }
        //3.释放资源
        outputStream.close();
        socket.close();
    }
}

服务端代码

public class Server {
    public static void main(String[] args) throws IOException {
        //1.创建一个服务器ServerSocket
        ServerSocket serverSocket = new ServerSocket(10086);

        //2.调用accept()方法,获取到请求的客户端Socket
        Socket socket = serverSocket.accept();

        //3.获取输入流,读取客户端发送的数据
        InputStreamReader isr = new InputStreamReader(socket.getInputStream());
        int b;
        while((b = isr.read()) != -1) {
            System.out.print((char)b);
        }
        //4.关闭流和socket
        isr.close();
        socket.close();
    }
}

2.Demo2 接收和反馈

 客户端代码

public class CilentType {
    public static void main(String[] args) throws IOException {
        //1.创建客户端socket
        Socket socket = new Socket("127.0.0.1", 10086);
        //2.获取输出流
        OutputStream outputStream = socket.getOutputStream();
        //3.写数据
        outputStream.write("我是客户端".getBytes());

        //在此写一个结束标记
        socket.shutdownOutput();
        //4.接收服务端的回复
        InputStreamReader isr = new InputStreamReader(socket.getInputStream());
        int b;
        while ((b = isr.read()) != -1) {
            System.out.print((char) b);
        }
        //关闭资源
        outputStream.close();
        isr.close();
        socket.close();
    }
}

服务端代码:

public class ServerType {
    public static void main(String[] args) throws IOException {
        //1.创建一个服务器ServerSocket
        ServerSocket serverSocket = new ServerSocket(10086);
        //2.监听客户端的连接
        //没有客户端连接,会阻塞在这里
        Socket socket = serverSocket.accept();
        //3.获取输入流
        InputStream inputStream = socket.getInputStream();
        //转换为字符流,避免出现中文乱码
        InputStreamReader isr = new InputStreamReader(inputStream);
        //4.读数据
        int b;
        //细节:
        //read方法会从连接通道中读取数据
        //如果客户端没有发送数据,会阻塞在这里
        //需要一个结束标记,此处循环才会停止。
        while ((b = isr.read()) != -1) {
            System.out.print((char) b);
        }
        //5.写回数据
        String str = "我是服务端";
        socket.getOutputStream().write(str.getBytes());
        //关闭流
        inputStream.close();
        socket.close();
    }
}

 注意:

read方法会从连接通道中读取数据
        如果客户端没有发送数据,会阻塞在循环那里
        需要一个结束标记,循环才会停止。

3.Demo3 上传文件

客户端代码

public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 10086);
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("files\\xjj.jpg"));
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        byte[] buffer = new byte[1024];
        int b;
        while ((b = bis.read(buffer)) != -1) {
            bos.write(buffer, 0, b);
        }
        bos.flush();
        socket.shutdownOutput();
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line = br.readLine();
        System.out.println(line);
        socket.close();
    }
}

服务端代码 

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(10086);
        Socket socket = serverSocket.accept();
        BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy\\a.jpg"));
        int b;
        byte[] buf = new byte[1024];
        while ((b = bis.read(buf)) != -1) {
            bos.write(buf, 0, b);
        }
        bos.flush();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        bw.write("服务端接收到了数据!");
        bw.newLine();
        bw.flush();
        socket.close();
        serverSocket.close();
    }
}

 注意注意注意:1.缓冲字节流是需要刷新的  2.流不要随意的关闭,不然就导致socket关闭了

4.Demo4 文件名重复问题

这道代码只需要在上一题的基础上,修改服务端的代码,保存文件的名字用下面的UUID类生成唯一的标识码。 

 

5.Demo5 上传文件多线程版本

使用循环+多线程

服务端代码

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(10086);
        while (true) {
            Socket socket = serverSocket.accept();
            MyRunnable mr = new MyRunnable(socket);
            new Thread(mr).start();
        }
    }
}

 线程类代码

public class MyRunnable implements Runnable{
    Socket socket;

    public MyRunnable(Socket socket) {
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
            String name = UUID.randomUUID().toString().replace("-", "")+".jpg";
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy\\"+name));
            int b;
            byte[] buf = new byte[1024];
            while ((b = bis.read(buf)) != -1) {
                bos.write(buf, 0, b);
            }
            bos.flush();
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            bw.write("服务端接收到了数据!");
            bw.newLine();
            bw.flush();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

客户端代码(和上面的一样)

public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 10086);
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("files\\xjj.jpg"));
        BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
        byte[] buffer = new byte[1024];
        int b;
        while ((b = bis.read(buffer)) != -1) {
            bos.write(buffer, 0, b);
        }
        bos.flush();
        socket.shutdownOutput();
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        String line = br.readLine();
        System.out.println(line);
        socket.close();
    }
}

6.Demo6  线程池优化版本

在上一道题的代码的基础上,修改服务端的代码,增加一个线程池管理线程

修改后的服务端的代码

public class Server {
    public static void main(String[] args) throws IOException {
        //创建自定义线程池
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                3,//核心线程数
                10,//最大线程数
                60,//空闲时间
                TimeUnit.SECONDS,//时间单位
                new ArrayBlockingQueue<>(2),//阻塞队列
                Executors.defaultThreadFactory(),//线程工厂
                new ThreadPoolExecutor.AbortPolicy()//拒绝策略
        );
        ServerSocket serverSocket = new ServerSocket(10086);
        while (true) {
            Socket socket = serverSocket.accept();
            MyRunnable mr = new MyRunnable(socket);
            threadPoolExecutor.submit(mr);
        }
    }
}

7.Demo7 接收浏览器的信息并打印

 

 这道题只需要服务端的代码,然后用浏览器去访问服务端

给个Demo1的服务端代码

public class Server {
    public static void main(String[] args) throws IOException {
        //1.创建一个服务器ServerSocket
        ServerSocket serverSocket = new ServerSocket(10086);

        //2.调用accept()方法,获取到请求的客户端Socket
        Socket socket = serverSocket.accept();

        //3.获取输入流,读取客户端发送的数据
        InputStreamReader isr = new InputStreamReader(socket.getInputStream());
        int b;
        while((b = isr.read()) != -1) {
            System.out.print((char)b);
        }
        //4.关闭流和socket
        isr.close();
        socket.close();
    }
}

先运行服务端的代码,再打开浏览器,输入127.0.0.1:10086访问服务端

服务端在控制台输出

 

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

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

相关文章

看图学sql之sql的执行顺序

学完前面的内容&#xff0c;我们已经掌握了基本的sql语法了&#xff0c;那我们学的 select, distinct, from, where,group by, having, order by, limit 他们具体的执行顺序是什么样的呢&#xff1f; 语法&#xff1a; SELECT distinct column1, column2 FROM table1 join …

关系型数据库管理系统--MySQL

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

【经验总结】ShardingSphere5.2.1 + Springboot 快速开始

Sharding Sphere 官方文档地址&#xff1a; https://shardingsphere.apache.org/document/current/cn/overview/maven仓库&#xff1a;https://mvnrepository.com/artifact/org.apache.shardingsphere/shardingsphere-jdbc 官方的文档写的很详尽到位&#xff0c;这里会截取部分…

基于Retina+PFLD+CNN人脸关键点及表情识别

对图片/视频中的人脸进行检测&#xff0c;并绘制人脸框。然后对检测到的人脸进行关键点识别&#xff0c;并进行绘制。最后根据人脸关键点&#xff0c;裁剪出人脸&#xff0c;判断该人脸的表情。 基于此&#xff0c;分别使用retina进行人脸检测&#xff0c;PFLD进行人脸关键点识…

软硬链接详解

目录 一、软硬链接命令 二、特征 三、相关知识 一、软硬链接命令 ln -s target link_name-s&#xff1a;选项表示创建一个符号链接&#xff08;软链接&#xff09;&#xff0c;如果没有-s就是硬链接target&#xff1a;是要指向的目标文件或目录的路径。link_name&#xff1…

「HarmonyNextOS」页面路由跳转Router更换为Navigation

前言 前段时间&#xff0c;鸿蒙发布了HarmonyNextOS系统&#xff0c;API直接升级到了12&#xff0c;许多API都发生了改变&#xff0c;页面跳转页从当初推荐的Router变换成Navigation&#xff0c;并且从API Version 10之后&#xff0c;都推荐使用NavPathStack来实现页面路由&am…

Go语言项目实战班04 Go语言课程管理系统项目实战 20240807 课程笔记和上课代码

预览 课程特色 本教程录制于2024年8月8日&#xff0c;使用Go1.22版本&#xff0c;基于Goland2024进行开发&#xff0c;采用的技术栈比较新。 每节课控制在十分钟以内&#xff0c;课时精简&#xff0c;每节课都是一个独立的知识点&#xff0c;如果有遗忘&#xff0c;完全可以当…

【JavaEE】synchronized原理

目录 前言 synchronized特性 synchronized特点 synchronize的加锁过程 1.无锁-->偏向锁 2.偏向锁->轻量级锁 3.轻量级锁->重量级锁 锁的优化操作 1.锁消除 2.锁粗化 3.自适应自旋锁 相关面试题 1.什么是偏向锁&#xff1f; 2.synchronized的实现原理是什…

LVS原理及实例

目录 LVS原理 LVS概念 lvs集群的类型 lvs-nat 解释 传输过程 lvs-dr 解释 传输过程 特点 lvs-tun LVS&#xff08;Linux Virtual Server&#xff09;常见的调度算法 防火墙标记&#xff08;Firewall Marking&#xff09;结合轮询调度 实战案例 lvs的nat模式配置 …

代码随想录算法刷题训练营day49:LeetCode(42)接雨水、LeetCode(84)柱状图中最大的矩形

代码随想录算法刷题训练营day49&#xff1a;LeetCode(42)接雨水、LeetCode(84)柱状图中最大的矩形 LeetCode(42)接雨水 题目 代码 import java.util.Stack;class Solution {public int trap(int[] height) {//用单调栈进行操作int sum0;Stack<Integer> stacknew Stac…

计算机的错误计算(五十六)

摘要 展示大数的正切函数值的错误计算。 由计算机的错误计算&#xff08;五十五&#xff09;知&#xff0c;国际IEEE 754 标准给出的正切函数的定义域是整个实数域范围。那么&#xff0c;在该范围内&#xff0c;软件的计算效果如何呢&#xff1f; 例1. 计算 . 在 Python下计…

字体识别验证码的介绍!

字体识别验证码 ​是一种安全机制&#xff0c;‌通过要求用户识别特定字体来验证用户的身份或防止自动化攻击。‌这种验证码通常包含一些经过特殊设计的字符&#xff0c;‌需要用户根据这些字符的特定样式&#xff08;‌如字体、‌字形等&#xff09;‌来进行识别和输入。‌字…

html+css网页制作 博云丝网5个页面 无js ui还原度100%

htmlcss网页制作 博云丝网5个页面 无js ui还原度100% 网页作品代码简单&#xff0c;可使用任意HTML编辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取…

el-tree限制选中个数

el-tree限制选中个数 <el-treestyle"max-width: 600px":data"Treedata":check-strictly"true"show-checkboxnode-key"id":props"defaultProps":default-expanded-keys"[1, 2]"ref"treeRef"check&quo…

Java数组类型

目录 一维数组 一维数组的声明 动态数组初始化 静态数组的初始化 一维数组的访问 数组长度 数组的遍历操作 数组中的默认值 数组中的两个常见异常 越界访问异常ArrayIndexOutOfBoundsException 空指针异常NullPointerException Java中的内存划分 一维数组的内存分…

pdf怎么加密码怎么设置密码?pdf加密码的几种设置方法

在数字化时代&#xff0c;信息的保密性与安全性日益成为我们不可忽视的重要环节。尤其对于包含敏感信息或个人隐私的PDF文档而言&#xff0c;保护其免受未授权访问的侵扰显得尤为重要。通过为PDF文档设置密码保护&#xff0c;我们能够筑起一道坚实的防线&#xff0c;确保只有拥…

危化品安全生产风险监测预警系统的构建与实施

引言 1、背景与重要性 在现代工业生产中&#xff0c;危险化学品&#xff08;简称“危化品”&#xff09;的使用和管理日益广泛。它们在化工、制药、能源等多个领域中扮演着不可或缺的角色。然而&#xff0c;危化品因其固有的易燃、易爆、腐蚀、有毒等特性&#xff0c;一旦管理…

Git使用错误分析

一.fatal: Pathspec is in submodule 我做了这样的错误操作&#xff0c;在一个仓库下的一个子目录&#xff0c;执行了git init 创建了一个子仓库&#xff0c;然后想删掉这个子仓库&#xff0c;就只删除了该子目录下的.git文件夹&#xff0c;而没有删除缓存&#xff0c;执行如下…

java: Internal error in the mapping processor: java.lang.NullPointerExceptio

java: Internal error in the mapping processor: java.lang.NullPointerExceptio 解决办法&#xff1a;idea里面加参数-Djps.track.ap.dependenciesfalse即可

Java程序设计:Java 网络聊天室客户端

相关网络编程前两篇文章&#xff1a;Java程序设计&#xff1a;Java网络编程实验 服务端部分见上一篇文章&#xff1a;Java程序设计&#xff1a;Java网络聊天室服务端 目录 1 实验名称 2 实验目的 3 实验源代码 4 实验运行结果图 5 总结 1 实验名称 Java 网络聊天室客户端 …