java之网络编程篇
前言
网络编程就是计算机和计算机之间通过网络进行数据传输,下面介绍一些概念和如何实现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();//指定接收端的组播ipInetAddress 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.创建一个服务器ServerSocketServerSocket 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.创建客户端socketSocket 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.创建一个服务器ServerSocketServerSocket 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.创建一个服务器ServerSocketServerSocket serverSocket = new ServerSocket(10086);//2.调用accept()方法,获取到请求的客户端SocketSocket socket = serverSocket.accept();//3.获取输入流,读取客户端发送的数据InputStreamReader isr = new InputStreamReader(socket.getInputStream());int b;while((b = isr.read()) != -1) {System.out.print((char)b);}//4.关闭流和socketisr.close();socket.close();} }
2.Demo2 接收和反馈
客户端代码
public class CilentType {public static void main(String[] args) throws IOException {//1.创建客户端socketSocket 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.创建一个服务器ServerSocketServerSocket 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;}@Overridepublic 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.创建一个服务器ServerSocketServerSocket serverSocket = new ServerSocket(10086);//2.调用accept()方法,获取到请求的客户端SocketSocket socket = serverSocket.accept();//3.获取输入流,读取客户端发送的数据InputStreamReader isr = new InputStreamReader(socket.getInputStream());int b;while((b = isr.read()) != -1) {System.out.print((char)b);}//4.关闭流和socketisr.close();socket.close();} }
先运行服务端的代码,再打开浏览器,输入127.0.0.1:10086访问服务端
服务端在控制台输出
相关文章:

java之网络编程篇
前言 网络编程就是计算机和计算机之间通过网络进行数据传输,下面介绍一些概念和如何实现UDP和TCP两种模式的传输。 一、常见的软件架构C/S和B/S C/S架构需要一个客户端软件程序服务器 B/S只需要打开网页服务器 C/S架构的优缺点和应用场景 优点:画面可以…...

stm32f103c8t6与TB6612FNG解耦测试
stm32f103c8t6与TB6612FNG解耦测试 本文操作方式: 忽略底层,只做上层, 所以前面全部照搬步骤,重在调试 文章目录 stm32f103c8t6与TB6612FNG解耦测试本文操作方式:创建基本工程(1)跳转此链接,创建(2)创建电机驱动文件夹(3)PWM原理(4)电机转动控制 oled调试和key调试(5)OLED转速…...
2253336 - 资源库 - OAC0 中的脱机状态
症状 资源库的状态显示为离线。 环境 SAP 内容服务器 6.50 或更高版本与 MaxDB 存储媒介结合使用对于状态为离线的资源库,测试报表 RSCMST 运行正常资源库可在应用程序中使用,没有任何问题 重现问题 启动事务 OAC0双击资源库按 "CSADMIN"…...

uni-app总结
1. <u-form-item label"报废人" ><u--input v-model"model.remark" border"bottom" placeholder"请输入"></u--input> </u-form-item> border"bottom" 报废日期 为了...

【JavaEE初阶】线程安全的集合类
📕 引言 我们之前讲过的集合类,,大部分都不是线程安全的. Vector, Stack, HashTable, 是线程安全的(都是自带了synchronized,不建议用), 其他的集合类不是线程安全的。 注意:加锁不能保证线程一定安全,不加锁也不能确定线程一定…...

关于Vue项目npm快捷键,点击run启动报错,及npm i也报错的解决办法
1.配置idea的npm 2.点击运行按钮 3.结果 分析原因及问题: npm i npm run dev 由于是刚刚从gitlab新拉的前端代码,可能没有用命令install过类似于没有编译过,所以执行一下上面的命令 结果报错如下: F:\tbyf\qjyy\hip-manager-ui&…...
React中,className属性自定义组件不生效的问题
在React中,className属性不仅适用于原生的HTML元素,也可以用于自定义组件。实际上,className属性是React中通用的属性,可以应用于任何React元素,无论是原生的HTML元素还是自定义的组件。 为什么使用className而不是cl…...
Ubuntu22.04搭建fabric开发环境、开发环境下运行链码
在智能合约开发过程中,开发人员需要一种快速、迭代地测试链码包的方法,而无需为每次修改运行链码生命周期命令。 使用 Fabric 二进制文件并启动peer处于开发模式(“DevMode”),然后将链码连接到peer。它允许您启动链代…...

[BSidesCF 2019]Kookie1
打开题目,看到 根据提示,账号:cookie。密码:monster。试一下登录,登陆成功 抓包看看信息 根据提示, 看一下返回包 账号要加username要改成admin,改一下试试 构造cookie 直接得到flag flag{c…...
LCM红外小目标检测
根据站内的matlab代码修改成python版本。 import numpy as np import matplotlib.pyplot as plt import cv2 from pylab import mpl# 设置中文显示字体 mpl.rcParams["font.sans-serif"] ["SimHei"]def LCM_computation(patch_LCM_in):row, col patch_L…...

振德医疗选择泛微千里聆RPA,助力电商、人事业务流程自动化
振德医疗用品股份有限公司成立于1994年,中国A股上市公司,是医用敷料和感控防护产品主要的供应商之一。 (图片素材来自振德医疗官网) 振德医疗的业务在线上线下齐发力。目前拥有5个国内生产基地,3个海外工厂࿰…...

VBA高级应用30例应用3在Excel中的ListObject对象:创建表
《VBA高级应用30例》(版权10178985),是我推出的第十套教程,教程是专门针对高级学员在学习VBA过程中提高路途上的案例展开,这套教程案例与理论结合,紧贴“实战”,并做“战术总结”,以…...

IP 地址在 SQL 注入攻击中的作用及防范策略
数据库在各个领域的逐步应用,其安全性也备受关注。SQL 注入攻击作为一种常见的数据库攻击手段,给网络安全带来了巨大威胁。今天我们来聊一聊SQL 注入攻击的基本知识。 SQL 注入攻击的基本原理 SQL 注入是通过将恶意的 SQL 代码插入到输入参数中…...
Unity VR黑屏
picosdk里面的,有修改 using System.Collections; using System.Collections.Generic; using UnityEngine;public class ScreenFade : MonoBehaviour {[Tooltip("颜色")]public Color fadeColor new Color(0.0f, 0.0f, 0.0f, 1.0f);private int renderQ…...
Vue.js 中使用 Watcher 的强大场景和案例
目录 表单验证 示例代码: HTML: 获取 API 数据 示例代码: HTML: 深度监听对象变化 示例代码: HTML: 观察多个数据源 示例代码: HTML: Vue.js 是一个流行的前端框架,以其直观的数据绑定和组件驱动的开发模式而闻名。其中,watch 功能是其响应式编程模型…...

《实现 DevOps 平台(2) · GitLab CI/CD 交互》
📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…...

【机器学习sklearn实战】岭回归、Lasso回归和弹性网络
一 sklean中模型详解 1.1 Ride regression 1.2 Lasso regression 1.3 ElasticNet 二 算法实战 2.1 导入包 import numpy as np import pandas as pd from sklearn import datasets from sklearn.model_selection import train_test_split, GridSearchCV from sklearn.linear…...
Python 爬虫项目实战六:抓取猫眼电影排行榜的数据
在这篇博客中,我们将通过一个实际的Python爬虫项目,详细讲解如何抓取网页数据。本次选择的实战项目是抓取猫眼电影排行榜的数据,通过这个项目,你将学会如何使用Python编写爬虫,从网页中提取有用的电影信息。 一、项目…...

YOLO系列:从yolov1至yolov8的进阶之路 持续更新中
一、基本概念 1.YOLO简介 YOLO(You Only Look Once):是一种基于深度神经网络的对象识别和定位算法,其最大的特点是运行速度很快,可以用于实时系统。 2.目标检测算法 RCNN:该系列算法实现主要为两个步骤&…...

欧拉系统离线安装界面ukui
1、官网下载安装镜像iso后,默认没有gui openEuler | 开源社区 | openEuler社区官网openEuler是一个开源、免费的 Linux 发行版平台,将通过开放的社区形式与全球的开发者共同构建一个开放、多元和架构包容的软件生态体系。同时,openEuler 也是…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
MySQL 8.0 事务全面讲解
以下是一个结合两次回答的 MySQL 8.0 事务全面讲解,涵盖了事务的核心概念、操作示例、失败回滚、隔离级别、事务性 DDL 和 XA 事务等内容,并修正了查看隔离级别的命令。 MySQL 8.0 事务全面讲解 一、事务的核心概念(ACID) 事务是…...

【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...