网访问内网机器:基于frp的内网穿透
随缘更新些我自己的博客网站里的文章吧
因为经常需要远程访问自己的机器,所以写一个博客记录一下
公网访问内网机器:基于frp的内网穿透
从公网中访问自己的私有设备向来是一件难事儿。
1. 为什么需要内网穿透?
A. 计算机网络
如何在自己的机器上访问另外一台机器?一台机器本身是一个独立的整体,可以直接访问本身所存储的文件。而如果现在有两台机器的话,机器A想要访问机器B上的文件,该怎么做?
事实上,当两台、乃至多台机器在一起的时候,就构成了一个以单台计算机为节点,以计算机和计算机之间的链接为边的网络,即计算机网络。我们访问另外一台计算机文件,就需要通过计算机网络来实现。
计算机网络中有一个比较重要的问题,就是如何标识每一台计算机。作为人,我们能很简单的知道,这是Jack Wang的Mac、那是Sarah的Windows、那是课题组公用的Linux,但是对于计算机来说,这是很难的。
所以类似于身份证能够识别不同的人一样,给组成计算机网络中的每一台设备一个编号,这个编号就作为每一台机器在网络中的标识,利用这个编号,能够找到需要访问的计算机。这个编号称为IP地址
所以,想要访问另外一台电脑,就需要知道对方的IP地址,然后才能访问。
B. 私网间互相访问
IP地址根据最初的设定,分为ABC几类。直白的来说就是有一些IP地址是保留给局域网使用(私网),剩下的IP地址全球共享(公网)
- 公网IP地址是不能重复的。
- 保留给局域网使用的IP地址在不同的局域网间是可以重复的。例如:你家和我家可能都有
192.168.0.1
这个IP地址,而使用这个IP地址的设备在你的局域网中可能是你的手机,而在我的局域网中可能是我的PC。但是,保留给局域网使用的IP地址在同一个局域网内是不能重复的。例如:我家的192.168.0.1
这个IP地址只可能被一部设备使用,要么是我的手机,要么是我的PC。
因此,不同局域网内的IP地址可重复这一性质就导致了两台处于不同局域内机器互相连接可能存在问题:
- 我们在办公室中使用的PC连接了办公室的网络,因此具有一个私网的IP地址,可能是
192.168.0.1
;我们的手机连接办公室的网络,因此也具有一个私网地址,可能是192.168.0.2
- 我们需要连接的在家里的PC连接了家里的网络,因此具有一个私网的IP地址,可能是
192.168.0.2
那么我们使用在办公室内的机器连接192.168.0.2
这个地址的时候,我们本来想连接家里的PC,但是由于私网的IP地址可重复,我们可能会连接到同一局域网下的另外一台机器。
C. 借助公网设备作为跳板
解决问题的办法就是获得一个公网IP。因为世界上所有的网络在一起,构成了互联网,或者公网。公网IP在公网中是唯一的。所以不管我们处于哪个局域网,都可以访问到具有公网IP的机器。
所以解决方案就是:
- 机器A和机器B都先连接到公网机器。
- 因为连接在建立后通信是双向的,所以在机器A、B连接到公网机器后,可以和公网机器双向通信
- 而后机器A把需要访问的机器B上的文件路径传给公网机器
- 公网机器把文件路径通知给机器B
- 机器B把文件传输给公网机器
- 公网机器再把文件传输给机器A
这样利用公网机器作为跳板,就实现了处于两个私网的机器间的访问。这种解决方案称为内网穿透
,即借助一个具有公网IP的服务器作为跳板,来让处于其他私网的设备访问到内网中的机器。这样做类似于把内网穿透到公网上,因此称为内网穿透
.
D. 哪来的公网IP?
上面解决两个私网机器互相访问最核心的,就是要有一个具有公网IP的机器。而由于中国加入到互联网的时间比较晚,所以分到的公网IP就比较少。原来很早的时候,打电话免费就可以申请得到一个公网IP,但现在运营商因为IP地址短缺不给你分配公网IP地址。
如果花钱买的话,目前市场中常用的网络有移动宽带、联通宽带、电信宽带,不同的网络运营商提供业务办理不同,收取的费用标准也存在一定的不同。一般情况,申请公网IP大概需要1000-2000元,具体的收费标准还需要以当地各大网络运营商提供的具体解决方案为准。所以就很贵。
所以就出现了一些服务商,他们购买了公网IP,然后架设了公网机器,我们只需要购买这些服务商提供的跳板服务/穿透服务就行了。但是这样功能非常有限,只有跳板服务,可玩性和功能性不高。
因此,我们不如直接租一个具有公网IP的服务器,然后自己架设跳板服务/穿透服务即可
2. frp搭建内网穿透
A. 什么是frp
既然我们需要进行内网穿透,肯定就需要有一个程序帮助我们去完成公网、私网机器连接的建立,公网机器上消息的转发等等功能,这个软件就是frp
。
简单地说,frp
就是一个反向代理软件,它体积轻量但功能很强大。利用他就可以实现反向穿透,即可以使处于内网或防火墙后的设备对外界提供服务。
它支持HTTP
、TCP
、UDP
等众多协议。我们今天使用的仅限于TCP
和UDP
,所以使用frp
是足够了

B. 机器配置信息
既然frp
需要建立公网机器和私网机器之间的连接,因此frp实际上是两个程序:
frpc
:即frp
客户端(client
),运行在需要被穿透到公网上的机器,即将来被远程访问的机器frps
:即frp
服务端(server
),运行在具有公网IP的机器上
而在运行的时候,frp
是根据配置文件中的描述来运行的。
因此,我们未来需要在公网机器和被远程访问的机器上分别下载frp
程序,并编写配置文件。
这里我的配置是:
- 公网机器是一台腾讯云服务器,后面就简称为服务器
- 公网地址是
81.68.123.84
- 用户名是
lighthouse
- 主机名是
VM-4-7-ubuntu
- 公网地址是
- 需要被穿透的机器(被其他私网机器访问的机器,即家里的机器)称为PC端
- 私网IP地址不重要
- 用户名是
jack
- 主机名是
jack-Alienware-Aurora-R13
注意,这里的公网地址
、公网机器用户名
需要使用你自己的!
C. 下载frp
1) 服务器下载frps
首先连接进服务器下载frp
服务端
ssh lighthouse@81.68.123.84
mkdir -p ~/opt/frps
cd opt/frps
wget -c https://github.com/fatedier/frp/releases/download/v0.51.0/frp_0.51.0_linux_amd64.tar.gz
注意,不同CPU架构下载的链接是不同的,我的服务器是
Intel
的CPU
,所以是x86_64
架构,下载amd64
版本的程序。你需要根据自己的服务器的架构去下载。所有版本的下载地址:https://github.com/fatedier/frp/releases
然后解压
tar xzvf frp_0.51.0_linux_amd64.tar.gz
ls -al frp_0.51.0_linux_amd64
因为目前是在服务器上配置frp
服务端,因此删去不需要的客户端程序:
rm frp_0.51.0_linux_amd64/frpc*
ls -al frp_0.51.0_linux_amd64
2) PC端下载frpc
步骤和服务器上下载frps
基本是一样的,这不过这里要删除的是frp
服务端
mkdir -p ~/opt/frpc
cd ~/opt/frpc
wget -c https://github.com/fatedier/frp/releases/download/v0.51.0/frp_0.51.0_linux_amd64.tar.gz
tar xzvf frp_0.51.0_linux_amd64.tar.gz
rm frp_0.51.0_linux_amd64/frps*
ls -al frp_0.51.0_linux_amd64
D. 配置frp
类似于下载,配置frp
也是分为PC端配置和服务器配置。

以SSH登录为例,frp
的工作流程如上图。假设现在远程主机(即键盘物理连接的机器)需要远程登录PC端,那么实际上就是远程主机使用PC机上的SSH程序,即访问PC机上的22
端口。
所以,当远程主机的一个ssh
请求来了之后:
- 远程主机的
ssh
请求打到服务器上的10001
端口 - 服务器的
10001
端口被正在运行的frps
程序监听。当frps
监听到一个ssh
请求后,将其通过服务器的的6006
端口发到PC端(已经建立链接的两台机器之间的通信是相互的) - PC端上正在运行的的
frpc
程序接收到远程主机发来的ssh
请求后,将其转发到本机的22
端口 - 远程主机的
ssh
请求最终被监听PC端22
端口的服务程序处理
因此:
- PC端(
frp
客户端)需要指定,将自己的22号端口映射为服务器(frp
服务端)的10001
端口,或者说需要将服务器的10001
端口的流量转发到PC端的22
端口 - 服务器(
frp
服务端)需要指定PC机(frp
客户端)需要通过哪个端口和服务器(frp
服务端)通信
可以看到,frp
其实最重要的就是转发了远程主机发来的数据包,因此frp
实际上工作在传输层。稍后我们在配置中就能看到,在frp
的配置文件中,我们需要指定服务器的哪个端口的哪种数据包需要转发到PC端的哪一个端口。
针对上面举的SSH
的例子,SSH
服务本质上是一个文本传输服务,只不过进行了加密,因此SSH
的数据包使用的是TCP
协议。后面穿透不同的服务的时候需要指定数据包的类型
1) 服务器配置
服务器端要配置的,实际上就只有bind_port
。因为listen_port
是需要frp
客户端指定的
ssh lighthouse@81.68.123.84
cd ~/opt/frps/frp_0.51.0_linux_amd64
vim frps.ini
将其中的bind_port
修改为6006
,这里是为了和上面的图配合起来,你也可以改成自己喜欢的。
cat frps.ini
服务器端的配置就结束了,最后得到的配置文件为:
# frps.ini,即服务端上的配置
[common]
bind_port = 6006
2) PC端配置
客户端的配置比服务端配置要复杂些,因为要指定远程端口的某种流量转发到本地的某个端口。
cd ~/opt/frpc/frp_0.51.0_linux_amd64
vim frpc.ini
按照上面介绍的
- 首先设置PC端的
frp
客户端连接到的frp
服务端的IP地址为服务器地址,即设置server_addr=81.68.123.84
- 然后设置PC端的
frp
客户端连接道frp
服务端监听的端口,即设置server_port=6006
接着编写一个新的规则
- 规则名字可以随便给,这里直接就是
Aurora-SSH
- 服务端需要监听服务端的
10001
端口 - 服务端转发的数据包类型就是
tcp
- 服务端转发的数据包的目的地址就是本机地址
127.0.0.1
- 服务端转发的数据包的目的端口就是
22
端口
最后得到的总配置文件为
注意,为了避免你的内网机器被穿透到我的服务器上,你需要修改一下
server_addr
,免得到时候我能登录你的内网机器^_^
# frpc.ini,即PC端上的配置
[common]
# 公网服务器IP地址
server_addr = 81.68.123.84
# 公网服务器上frps通过该端口和私网机器上的frpc通信
server_port = 6006[Aurora-SSH]
# 该规则所转发的数据包类型
type = tcp
# 数据包转发IP地址
local_ip = 127.0.0.1
# 数据包转发目的端口
local_port = 22
# 将公网服务器上该端口的type类型的包转发到本机
remote_port = 10001
所以总的来说就是:将81.68.123.84
服务器上的10001
端口接收到的tcp
数据包转发到本地的22
端口,并且通过服务器的6006
端口进行通信
E. 启动frp
首先启动服务器端的frps
ssh lighthouse@81.68.123.84
cd ~/opt/frps/frp_0.51.0_linux_amd64
./frps -c frps.ini| tee -a frps.log
这里把命令行输出到信息备份一份到frps.log
文件中
然后启动PC端的frpc
cd ~/opt/frps/frp_0.51.0_linux_amd64
./frpc -c frpc.ini | tess -a frpc.log
启动成功后,再检查一下服务器上的frps
,发现已经接收到了frpc
客户端发来的规则,开始监听端口10001
了
F. 验证
最后验证一下能否远程登录到PC端。
这里直接就在PC端下SSH
连接服务器的10001
端口,因为登录的是PC端的用户,所以用户名还需要是PC端的用户名,只不过此时SSH
服务器地址已经变成了服务器的地址
ssh jack@81.68.123.84 -p 10001
3. 番外:PC端开机自运行frpc
最后,服务器因为我们随时可以链接进去,所以使用tmux
开一个session
,保持frps
运行即可。但是PC端则需要我们事先手动运行frpc
。
如果我们运行了一些命令导致PC端重启了,那么再次启动的时候就会导致服务丢失。所以,我们希望PC端在重新启动的时候能够自动运行frpc
。
为此,我们使用Systemd来新建一个服务。关于Systemd后面会写点文章介绍,这里就先用吧。
Systemd介绍:
Systemd是一个用于Linux系统的系统和服务管理器。它被设计为替代传统的SysV初始化系统(init)和System V启动脚本,并提供了更先进的功能和特性。
Systemd的目标是改进系统的启动速度、效率和可靠性,并提供更好的系统管理和服务控制功能。它引入了一种并行启动机制,可以同时启动系统中的多个服务,加快系统启动时间。此外,Systemd还支持基于套接字激活的服务,可以在需要时按需启动或停止服务,提高系统资源利用率。
Systemd还引入了一种统一的单元文件(unit files)格式,用于描述系统服务、设备、挂载点等。这些单元文件位于
/etc/systemd/system/
和/usr/lib/systemd/system/
等目录下,通过这些单元文件,可以对系统的各个方面进行配置和管理。Systemd提供了一系列的命令行工具,用于管理和控制系统和服务,例如
systemctl
命令用于启动、停止、重启和管理系统服务,journalctl
命令用于查看系统日志。总的来说,Systemd是一个现代化的系统和服务管理器,它在Linux系统中扮演着重要的角色,改进了系统的启动和管理方式,提供了更好的性能和功能。它已经成为许多主流Linux发行版的默认初始化系统。
A. 编写启动脚本
首先编写一个脚本来运行frpc
cd ~/opt/frpc
# 创建一个软连接,方便后面更新版本
ln -s frp_0.51.0_linux_amd64 bin
vim start_frpc.sh
内容如下:
#! /bin/bashrun_folder=$(cd $(dirname $0) && pwd || exit)
bin_folder="${run_folder}/bin"cd ${bin_folder} && ${bin_folder}/frpc -c ${bin_folder}/frpc.ini 2>&1 | tee -a ${run_folder}/frpc.log
运行这个脚本就可以一键化直接运行frpc
了
chmox 755 start_frpc.sh
./start_frpc.sh
输出到终端的日志信息会保存到frpc.log
文件中
B. 开机运行启动脚本
编写完了开机脚本还不行,还需要开机就运行这个脚本。后面就是通过Systemd来设置开机运行这个脚本了。开机自运行的Systemd任务需要放在/usr/lib/systemd/system
目录下
首先新建一个Systemd任务,名字为frpc-client
,而后创建软连接方便修改
cd ~/opt/frpc
sudo touch /etc/systemd/system/frp-client.service
ln -s /etc/systemd/system/frp-client.service ./
sudo vim frp-client.service
然后编写内容如下:
# 这个部分定义了服务的基本信息, 这里是一个启动frpc的服务
[Unit]
Description=开机自动运行frpc任务
# 必须要在网络启动之后才能运行, 因为Systemd是多线程运行服务的
After=network.target
# 同时该任务以来网络, 因此声明启动网络服务是该服务的依赖
Wants=network.target# 这个部分定义了服务的运行参数和行为
[Service]
# 指定了服务的类型,这里是simple,表示是一个简单的服务,即执行指定的命令或脚本。
Type=simple
# 指定了运行服务的用户,这里是jack,表示以jack的身份运行服务
User=jack
# 这个参数很重要!无论是由于错误、异常退出还是手动停止,只要服务退出,它都应该立即重新启动。
# 这确保了服务的持续性,即使出现问题导致服务停止,Systemd也会自动重新启动它,以恢复服务的正常运行。
# 所以将其指定为always确保脚本会一直运行
Restart=always
# 指定了服务在重启之前的等待时间
RestartSec=5s
# 指定了服务可以打开的最大文件描述符数,这里是1048576
LimitNOFILE=1048576
# 指定了要运行的命令或脚本的绝对路径
ExecStart=/bin/bash /home/jack/opt/frpc/start_frpc.sh
# 服务重新加载(reload)时执行的命令或脚本。
ExecReload=/bin/bash /home/jack/opt/frpc/start_frpc.sh# 这个部分定义了服务的安装和启动配置
[Install]
# 下面这段不能少, 强制要求了在用户登录前运行启动脚本
WantedBy = multi-user.target
然后把这个启用这个任务
# 因为新建了一个开机启动任务,所以重新加载一下systemd守护进程
sudo systemctl daemon-reload
sudo systemctl enable frp-client.service
然后查看一下这个任务的状态
sudo systemctl status frp-client.service
因为目前只是加载了这个任务(表示启动时将会运行这个任务),而由于上次启动时还没运行这个任务,所以显示的是dead。
紧着这,启动一下这个服务
sudo systemctl start frpc-client.service
sudo systemctl status frpc-client.service
接下来重启一下PC端就行了,此时这个任务就会被运行
sudo reboot
# 重启后检查一下任务状态
sudo systemctl status frp-client.service
相关文章:

网访问内网机器:基于frp的内网穿透
随缘更新些我自己的博客网站里的文章吧 因为经常需要远程访问自己的机器,所以写一个博客记录一下 公网访问内网机器:基于frp的内网穿透 从公网中访问自己的私有设备向来是一件难事儿。 1. 为什么需要内网穿透? A. 计算机网络 如何在自己的机…...

【Spring框架】Spring读取与存储综合练习
练习 在 Spring 项⽬中,通过 main ⽅法获取到 Controller 类,调⽤ Controller ⾥⾯通过注⼊的⽅式调⽤ Service 类,Service 再通过注⼊的⽅式获取到 Repository 类,Repository 类⾥⾯有⼀个⽅法构建⼀个 User 对象,返…...

Python实现指定区域桌面变化监控并报警
在这篇博客中,我们将使用Python编程语言和一些常用的库来实现一个简单的区域监控和变化报警系统。我们将使用Tkinter库创建一个图形界面,允许用户选择监控区域,并使用OpenCV库进行图像处理和相似性比较,以检测区域内的变化&#x…...

【数据结构】实验五:栈
实验五 栈 一、实验目的与要求 1)熟悉栈的类型定义和基本操作; 2)灵活应用栈解决具体应用问题。 二、实验内容 1、判断回文数,回文是指正读反读均相同的字符序列,如“1221”和“12321”均是回文,但“…...

⚡️⚡️Java多线程编程的高效、安全实践
⚡️ Java多线程编程的高效、安全实践⚡️ ☀️ 1 摘要☀️2 多线程编程基础☀️ 3 线程同步与互斥☀️ 4 并发集合类与原子操作☀️ 5 线程池与执行器框架☀️ 6 并发编程的最佳实践🌄 7 总结 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客…...

【云原生】Docker私有仓库registry
目录 1)用docker容器运行registry私有仓库服务。 2)运行私有仓库服务 3)镜像重命名(要上传的镜像名需要注明私仓的ip) 4)编辑docker配置文件(因为默认是拉取docker官方的镜像,需要重新指定) 5)其他dock…...

第十四届蓝桥杯大赛青少年省赛C++组试题真题 2023年5月
一、选择题 第 1 题 单选题 C中,bool类型的变量占用字节数为 ( )。 A. 1 B. 2 C. 3 D. 4 第 2 题 单选题 以下关于C结构体的说法,正确的是 ( )。 A. 结构体中只能包含成员变量,不能包含成员函数 B. 结构体不能从另一个结构体继承 …...

GAN论文精读
标题:Generative Adversarial Nets 摘要: 简写:作者提出了一个framework通过一个对抗的过程,在这里面会同时训练两个模型。 第一个模型为生成模型G,是用来抓住整个数据的分布 第二个模型为辨别模型D,是用来估计一个样本是否从G中产生。 …...
数据结构:计数排序(详解)
思路详解: 1 找到数组中的最大值、最小值 2 开辟一个统计每个数据出现次数的数组(总个数是最大值-最小值1,因为下标范围是0~最大值-最小值,闭区间统计个数要1) 3 遇到一个元素,在此元素-最小值作为下标的…...

1 请使用js、css、html技术实现以下页面,表格内容根据查询条件动态变化。
1.1 创建css文件,用于编辑style 注意: 1.背景颜色用ppt的取色器来获取: 先点击ppt的形状轮廓,然后点击取色器,吸颜色,然后再点击形状轮廓的其他轮廓颜色,即可获取到对应颜色。 2.表格间的灰色线…...

react-native项目安卓版本升级 compileSdkVersion 29->31
因为 react-native-ble-manager添加过程及碰到的问题 依赖 https://github.com/innoveit/react-native-ble-manager 参考:https://blog.csdn.net/withings/article/details/71378562 iOS 按react-native-ble-manager 文档在 【Info.plist】加了key之后能正常使用…...

【学习笔记】目标跟踪领域SOTA方法比较
目录 前言方法1 TraDeS:2 FairMOT:3 SMILEtrack:4 ByteTrack: 前言 常用于行人跟踪的多目标跟踪数据集包括:MOT 15/16/17/20、PersonPath22等… 为更好比较现有SOTA算法的检测性能,本博客将针对在各数据集上表现较优的算法模型进行介绍。(表…...

机器学习 深度学习编程笔记
sigmoid函数 def sigmoid(x):return 1.0 / (1np.exp((-x)))定义最小平方和损失函数 loss torch.nn.MSELoss()线性回归编程 如果不加噪音就成了正常的线性函数了,所以要加噪音。 torch.normal(0, 0.01, y.shape)torch.normal(0, 0.01, y.shape)是一个用于生成服从…...

18.背景轮播
背景轮播 html部分 <div class"container"><div class"slide active" style"background-image: url(./static/20180529205331_yhGyf.jpeg);"></div><div class"slide " style"background-image: url(./s…...

论文代码学习—HiFi-GAN(2)——鉴别器discriminator代码
文章目录 引言正文鉴别器多周期鉴定器多尺度鉴定器问题 总结 引言 这里翻译了HiFi-GAN这篇论文的具体内容,具体链接。这篇文章还是学到了很多东西,从整体上说,学到了生成对抗网络的构建思路,包括生成器和鉴定器。细化到具体实现的…...
Linux Shell 脚本编程学习之【第3章 正则表达式 (第二部分) grep命令】
第3章 正则表达式 (第二部分) 4 grep命令4.1 基本用法4.2 参考命令4.2.1 双引号4.2.2 -c 输出匹配行数4.2.3 -h 或 -l 不显示或只显示文件名4.2.4 -s 不显示错误信息4.2.5 -r 递归显示本级目录及下级目录4.2.6 -w 匹配完整词 -x 匹配完整行4.2.7 -q 退出…...

大语言模型LLM
目录 一、语言模型的发展 语言模型(Language Model,LM)目标是建模自然语言的概率分布,具体目标是构建词序列w1,w2,...,wm的概率分布,即计算给定的词序列作为一个句子出现可能的大小P(w1w2...wm)。但联合概率P的参数量…...

自学网络安全(黑客)的误区
前言 网络安全入门到底是先学编程还是先学计算机基础?这是一个争议比较大的问题,有的人会建议先学编程,而有的人会建议先学计算机基础,其实这都是要学的。而且这些对学习网络安全来说非常重要。 一、网络安全学习的误区 1.不要…...

@Conditional
Conditional Conditional 是 spring framework 中提供的一个条件注解,,满足条件就注入,不满足就不注入ioc Condtional 需要和 Condition接口 一起用: 返回true注入,返回false不注入,, 里面有一…...

【Linux】网络基础之TCP协议
目录 🌈前言🌸1、基本概念🌺2、TCP协议报文结构🍨2.1、源端口号和目的端口号🍩2.2、4位首部长度🍪2.3、32位序号和确认序号(重点)🍫2.4、16位窗口大小🍬2.5、…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

初学 pytest 记录
安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)
Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...