首页
游戏
影视
直播
广播
听书
音乐
图片
更多
看书
微视
主播
统计
友链
留言
关于
论坛
邮件
推荐
我的硬盘
我的搜索
我的记录
我的文件
我的图书
我的笔记
我的书签
我的微博
Search
1
在IC617中进行xa+vcs数模混仿
84 阅读
2
科普:Memory Compiler生成的Register file和SRAM有何区别?
74 阅读
3
virtuoso和empyrean alps模拟仿真和混仿教程
74 阅读
4
后仿中$setup,$hold与$setuphold
45 阅读
5
文档内容搜索哪家强? 15款文件搜索软件横向评测
36 阅读
默认分类
芯片市场
数字电路
芯片后端
模拟电路
芯片验证
原型与样片验证
算法与架构
DFX与量产封装
PC&Server OS设置
移动OS设置
软件方案
新浪备份
有道备份
登录
Search
标签搜索
python
Docker
vscode
linux
systemverilog
vcs
STM32
PyQT
EDA
FPGA
gvim
cadence
Alist
xilinx
UVM
uos
macos
package
MCU
risc-v
bennyhe
累计撰写
378
篇文章
累计收到
31
条评论
首页
栏目
默认分类
芯片市场
数字电路
芯片后端
模拟电路
芯片验证
原型与样片验证
算法与架构
DFX与量产封装
PC&Server OS设置
移动OS设置
软件方案
新浪备份
有道备份
页面
游戏
影视
直播
广播
听书
音乐
图片
看书
微视
主播
统计
友链
留言
关于
论坛
邮件
推荐
我的硬盘
我的搜索
我的记录
我的文件
我的图书
我的笔记
我的书签
我的微博
搜索到
378
篇与
的结果
2025-08-29
模拟IC设计:sigma delta ADC原理分析
KGback IP.与SoC设计2022年05月09日12:10江苏 一. ADC原理对于 Nyquist 和 Shannon 定理的检验将证明:ADC 采样频率的选择与最大输入信号频率对输入信号带宽的比率有很强的相关性。Nyquist准则(欠采样准则)如果要从相等时间间隔取得的采样点中,毫无失真地重建模拟信号波形,则采样频率必须大于或等于模拟信号中最高频率成份的两倍。因而对于一个最大信号频率为 fMAX的模拟信号 fa,其最小采样频率 fs,则有 fs ≥ 2 * fMAXNyquist频率:采样频率的一半,即 fs/2。从理论上来讲奈奎斯特频率正好大于输入信号的最大频率。Shannon定理一个带宽为fb的模拟信号,采样速率必须为 fs > 2fb,才能避免信息的损失。信号带宽可以从 DC 到 fb(基带采样),或从 f1 到f2,其中 fb = f2-f1(欠采样)。信号混叠如果不满足采样定理条件,采样后的信号的频率就会重叠。即被采样信号中高于采样频率一半(fs/2)的那部分频率成分将被重建成低于fs/2信号。这种频谱的重叠导致的失真称为混叠。(可借助车轮效应理解)(1)出现原因:若采样频率小于2倍的信号频率,即 fs < 2 * fa,那么,采样后的信号将存在混叠。理论上,如果信号中没有高于奈奎斯特频率的频率成分,那么则不存在混叠。(2)解决办法:a.提高采样频率 fs,一般实际应用中保证 fs 为 fMAX 的2.56~4倍。b.加一个低通滤波器:抗混叠滤波器理想状态下,该滤波器可使低于奈奎斯特频率的频率通过,移除高于奈奎斯特频率的频率成分性能指标(1)静态指标a.积分非线性(INL):输入一输出特性曲线与连接两端点的直线之间的最大偏差b.微分非线性(DNL):在输入轴上两个连续码转换点之间的差值与理想 1LSB 值的最大偏差c.失调:直线AB通过端点的垂直截距d.增益误差:直线AB的斜率与理想值1之间的偏差(2)动态指标a.信号与噪声失真比(SNDR):是当输入为正弦时,输出端信号功率与总噪声及谐波功率的比。b.动态范围:满量程正弦输入功率与肼限=0 dB时的正弦输入功率的比值c.总谐波失真:所有谐波能量(除去基波)之和除以基频的能量二. Σ-Δ 原理0.常用单级分类(1)根据modulator是否使用开关电容电路分a.连续时间模式(无开关电容):优点:功耗更小,无开关电容对时钟噪声不敏感,调制速度更快,常用于转换较高频率信号。缺点:要通过RC值来确定的积分系数,而不是像离散时间模式是用电容比值来确定的;对反馈回来的脉冲波形比较敏感,它会影响输入信号。b.离散时间模式则(有开关电容)与前者相反。(2)根据modulator阶数分所谓阶数指的是sigma—Delta调制器中积分器的个数。一般阶数越高幅频特性越好,低频段的衰减也越厉害,高频段的通过性越好所能达到的有效位数越大,但是延迟也会很大,也会减小输入信号的摆幅,另外,由于噪声在高频的幅值过大,会使整个系统的稳定性降低。(3)根据量化器的位数分可以分为一位调制器和多位调制器。使用多位量化器可以增加SNR,使系统容易稳定,产生较少的谐波分量,使降采样滤波器变得相对简单;但是多位量化器增加了ADC的复杂性,并且要求用于反馈的多位DAC有足够的精度来保证最后量化的精度。1.基本原理(图片来源于ANALOG DEVICES) (1)过采样指以高于信号带宽2倍或其最高频率对其采样的过程。K即为过采样率(OSR)。目的:a. 由于采用 Kfs 采样频率,均方根值为 q/√12 的量化噪声分布在 DC 到 Kfs/2 的带宽范围内,降低了某一频率下的噪声幅值,从而提高了信噪比,根据信噪比(SNR)和实际分辨率(ENOB)公式:ENOB=(SNR-1.76)/6.02 (SNR=6.02*N+1.76)可见提高了实际分辨率b.同时减轻了模拟抗混叠滤波器的要求(2)量化噪声整形(采样频率和量化值之间的关系,红线是实际电压值)离散化的阶梯型与红色的模拟信号相减的值即为量化噪声。实际上,阶梯型线条包围的面积和模拟信号包围的面积是相等的,即二者能量总量是相等的。量化噪声是消除不了的。根据频域线性模型y和x的关系,f越大,Q引起的噪声就越大,即类似高通滤波器(x部分则是低通滤波器)(3)数字抽取滤波通过数字滤波器将比较器输出的高频一位或多位量化值转换为频率较低的多位量化值。可理解为降采样滤波器可将n个输入信号加起来,然后除以n,这样获得输入的平均值。优点:当采样频率下降n倍时,fs/n及其谐波分量处的噪声被混叠到信号带内,其引入的噪声会比较小。(4)数据流的计算该部分举例分析:若调制器DAC的参考电压Vref为1V,现输入模拟电压值0.5V,则调制器输出为011101110111的序列,如图所示:3/4代表调制器分辨率为2,6/8代表分辨率为3则实际电压Vin=(3/4-2/4)(1-(-1))=0.5V, 即Vin=(weight(1)-1/2)Vref*2(5)频域线性模型输出值y和输入值x,以及量化噪声Q,信号频率f之间的关系2.ADC组成(图片来源于ANALOG DEVICES)(1)模拟部分:a.模拟抗混叠滤波器,b.ADC部分:一个比较器、一个基准电压源、一个开关以及一个或多个的积分器与模拟求和电路(2)数字部分:一个DSP(通常但不总是低通滤波器使用)三.设计流程1.数字抽取滤波器设计在设计数字滤波器时,滤波器的采样频率就是前端AD的采样频率。不同阶数的CIC滤波器的延迟问题:当数字滤波器处理来自Σ-Δ调制器的数据流的移动平均值时,存在一个相关的建立时间。该延迟对所有FIR滤波器是固定的,但对不同阶数的CIS滤波器,该延迟是不同的。通常用两项来描述该延迟:群延迟和建立时间。群延迟描述从输入端存在模拟信号到在数字输出端看到它的延迟时间。例如对于单音正弦波,群延迟就是从模拟输入端存在该正弦波电压峰值到该峰值出现在数字输出端的时间差。建立时间是指数字滤波器的全部均值时间。如果模拟输入端有一个阶跃,那么需要经过滤波器的完全建立时间, ADC的数据输出才与阶跃之前的输入无关。还可能存在其他延迟,如滤波器的计算时间等。本次设计的数字抽取滤波器为3阶的CIC滤波器,与一般的FIR滤波器相比,后者则需要大量的乘法器,而前者只需要加法器和延时,简化了运算,适合用于抽取前级和内插后级等告诉场合,但是也有明显不足:幅频特性无法像 FIR 那样灵活设计,因而有时在抽取的后级会用 FIR 来整形。因此该设计主要由级联积分梳状(CIC)抽取滤波器、CIC补偿滤波器和半带(HB)滤波器组成。cIc抽取滤波器作为数字抽取滤波器的第一级来达到降速作用;CIC补偿滤波器用来补偿通带的衰减;HB滤波器则用作抽取滤波器的阻带衰减及进一步降低采样频率。用FDAtool设计CIC decimator时,通带增益不是0dB,需要级联一个常数增益滤波器,CIC滤波器增益为D^Q,D是抽取因子,Q是级数,常数增益滤波器增益设置为1/(D^Q),就行,在脚本中输入 G=dfilt.scalar,G.Gain=1/(D^Q);然后从工作区引入滤波器,设置完参数和CIC级联。本文来源:https://blog.csdn.net/qq_39815222/article/details/103248394来自微信
2025年08月29日
0 阅读
0 评论
0 点赞
2025-08-29
博文速递:Clock Gating
VLSI SoC Design IP与SoC设计 2022年05月09日 12:10 江苏Clock GatingClock signal is the highest frequency toggling signal in any SoC. As we discussed in the post: Need for Low-Power Design Methodology, the capacitive load power component of the dynamic power is directly proportional to the switching frequency of the devices. This implies that clock path cells would contribute maximum to the dynamic power consumption in the SoC. Power consumption in the clock paths alone contribute to more than 50% of the total dynamic power consumed within modern SoCs. Power being a very critical aspect of the design, one needs to make prudent efforts to reduce this. Clock Gating is one such method. Let's try and build further on this perspective.Clock feeds the CLOCK pins all the Flip-Flops in the design. Clock Tree itself comprises of clock tree buffers which are needed to maintain a sharp slew (numerically small) in the clock path. Refer to the post Clock Transition for details. Consider the above figure. It is not necessary that the output of the flip-flop would be switching at all times. Modern devices support various low-power modes in which only a certain part of your SoC is working. This may include some key features pertaining to security or some critical functional aspects of your device. Apart from this, there are some configuration registers in your device which need to be programmed either once or very seldom. So, let's say, the above FF will not be switching states for a considerable period of time. If it is used the way it is, what's the problem? Power! Clock is switching incessantly. Clock Tree buffers are switching states and hence consuming power. So are the FFs. Remember that FF itself is made up of latches. So, despite the fact that input and output of the FF is not switching, some part of the latch is switching and consuming power.What could be done to alleviate the above problem? Clock Gating is one such solution. Here's how it'll help.If you place an AND gate at the clock path and knowing that you don't need a certain part of your device to receive clock, drive a logic '0' on the ENABLE pin. This would ensure that all the Clock Tree buffers and the sink pin of the FF are held at a constant value (0 in this case). Hence these cells would not contribute to dynamic power dissipation. However, they would still consume leakage power.Similarly, you can place an OR gate and drive it's one input to logic 1. Again, you would save on the dynamic power.However, a word of caution. The output of the AND gate feeding the entire clock path might be glitchy. See the following figure:Solution: The output won't be glitchy if the enable signal changes only when the CLOCK signal is low. So, all you gotta make sure is that ENABLE is generated by a negative-edge triggered FF. This would ensure that the signal is changing after the fall edge of the CLOCK signal.Similarly, while using an OR-gate, clock pulse would be propagated if the ENABLE signal changes when the CLOCK is high. Make sure that it is generated by a positive-edge triggered FF in order to avoid any glitch being passed onto the FFs. Why would a glitch be detrimental anyway? The answer is:Glitches constitute an edge! FF might sample the value because they are edge-triggered. But, problem is that all FFs have a certain duty cycle requirement (Also called Pulse-width check), which needs to be fulfilled in order to ensure that they don't go into METASTABILITY. And if an unknown state : X is propagated in a design, the entire functionality of the chip can go haywire!Some terminologies: •AND/NAND gate based clock gating is referred to as Active-High Clock Gating. •OR/NOR gate based clock gating is referred to as Active-Low Clock Gating.NAND and NOR clock gates work similar to AND and OR respectively.So, Clock Gating is an efficient solution to save dynamic power consumption in the design. Modern SoCs have many IPs integrated together. Placing a clock gate and enabling them in various possible combinations is what gives rise to different low-power modes in the device.If any content of this article infringes, please contact us to remove this article.来自微信
2025年08月29日
0 阅读
0 评论
0 点赞
2025-08-28
5 分钟,教你从零快速编写一个油猴脚本!
1T服务圈儿2022年05月07日17:30江苏来源:经授权转自 AirPython(ID:AirPython)作者:星安果Tampermonkey,又称 Greasemonkey 油猴脚本,是一款免费的浏览器扩展,可用于管理用户脚本,它本质上是对浏览器接口的二次封装油猴脚本可用于更改页面布局样式、完成页面自动化、去广告、下载影视等功能,适用于主流的浏览器官网:https://www.tampermonkey.net/index.php介绍Tampermonkey 特点包含:内置的编辑器,可以非常方便地管理、编辑用户脚本支持自动更新检查功能标签中脚本运行状态速览可以通过压缩文件、云存储进行脚本备份及还原通过面板新建一个用户脚本,默认会生成一个模板,模板内容如下:模板中会预设部分元数据,用于定义脚本的名称、版本号、更新方式、运行页面、权限等功能常见的元数据包含:@name - 油猴脚本的名称 @namespace 脚本的命名空间,用于确定脚本的唯一性 @version 脚本的版本号,用于脚本的更新 @description 脚本的描述信息 @author 作者 @require 定义脚本运行之前需要引入的外部 JS,比如:jQuery @match 使用通配符执行需要匹配运行的网站地址 @exclude 排除匹配到的网站 @grant 指定脚本运行所属的权限 @connect 用于跨域访问时指定的目标网站域名 @run-at 指定脚本的运行时机 @icon 用于指定脚本的图标,可以设置为图片 URL 地址或 base64 的字符串常见 API油猴提供了很多强大的 API,用于操作缓存及窗口等,如果不需要使用这些 API,可以声明权限为 none,即:@grant none2-1 打印日志用于在控制台中打印日志,便于调试// 授权 @grant GM_log // 在控制台打印日志 GM_log("Hello World");2-2 缓存管理包含对缓存的新增、获取、删除,在使用之前我们都需要使用关键字 @grant 进行授权//授权 // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue //设置缓存 GM_setValue("hello", true); //获取缓存,默认值为true GM_getValue("hello", true); //删除缓存 GM_deleteValue("hello")2-3 缓存监听有时候,我们需要对缓存中的某个键的值进行监听,当发生变化时,调用一个方法事件比如,这里新增了一个监听器,对键名为 hello 的值进行监听// 授权 // @grant GM_addValueChangeListener // @grant GM_removeValueChangeListener // 添加一个监听器 const listener_id = GM_addValueChangeListener('hello', function(name, old_value, new_value, remote){ if(hello == false){ //具体的调用方法 //.... } }) //监听监听器 GM_removeValueChangeListener(listener_id);2-4 打开一个标签格式:GM_openInTab(url, options)该 API 可用于打开一个新的标签页面其中,第一个参数用于指定新标签页面的 URL 地址,第二个参数用于指定页面展示方式及焦点停留页面// 授权 // @grant GM_openInTab // 打开新页面 var onpenNewTap = function (){ //打开百度页面 //active:true,新标签页获取页面焦点 //setParent :true:新标签页面关闭后,焦点重新回到源页面 newTap = GM_openInTab("https://www.baidu.com",{ active: true, setParent :true}); ...2-5 跨域请求在授予 GM_xmlhttpRequest 权限之后,就可以跨域发送请求了PS:第一次跨域请求时,会弹出请求对话框,需要选中允许,才能正常进行跨域请求// 授权 // @grant GM_xmlhttpRequest ... GM_xmlhttpRequest({ url:"http://www.httpbin.org/post", method:'POST', headers: { "content-type": "application/json" }, data:"", onerror:function(res){ console.log(res); }, onload:function(res){ console.log(res); } }); ...实战一下以某一新闻网站的自动加载下一页为例进行说明目标网站:IGh0dHBzOi8vd3d3LnBpbmd3ZXN0LmNvbS8=首先,我们使用关键字 @match 指定匹配的网站 URL,使用 @grant 设置权限 GM_log,使用关键字@run-at 指定执行时机为页面加载完成,即:document-end// ==UserScript== // @name 新闻查看更多 // @namespace com.xag.more // @version 0.1 // @license GNU General Public License v3.0 // @description 自动查看下一页 // @author xingag // @match 目标网站 // @icon 图标icon地址 // @grant GM_log // @run-at document-end // ==/UserScript== ...接着,添加一个定时任务,获取每一页底部的加载更多按钮最后,判断元素存在时,执行点击操作即可... (function() { 'use strict'; console.log("location.hostname:",location.hostname) if(location.hostname == "www.pingwest.com"){ setInterval(() => { const more_element = document.querySelector(".load-more-box").querySelector("a") if(more_element){ GM_log("元素存在,点击加载更多。。。") more_element.click(); } }, 2000); } })() ...总结本篇文章以一个简单的实例讲解了编写一个油猴脚本的完整流程为了提升开发效率,实际编写脚本可以使用 VS Code 编译器,安装插件 Tampermonkey Snippets 后再进行用户脚本开发当然,应对一些复杂的场景,可以借助一些优秀的脚手架框架https://github.com/kinyaying/wokoohttps://www.npmjs.com/package/create-tampermonkeyhttps://github.com/qianjiachun/vue3-tampermonkey来自微信
2025年08月28日
2 阅读
0 评论
0 点赞
2025-08-28
通过公网IP 云服务器做开源免费内网穿透推荐
本文以渗透的视角,总结几种个人常用的内网穿透,内网代理工具,介绍其简单原理和使用方法。nps1.1 简介nps是一款轻量级、高性能、功能强大的内网穿透代理服务器。目前支持tcp、udp流量转发,可支持任何tcp、udp上层协议(访问内网网站、本地支付接口调试、ssh访问、远程桌面,内网dns解析等等……),此外还支持内网http代理、内网socks5代理、p2p等,并带有功能强大的web管理端。一台有公网IP的服务器(VPS)运行服务端(NPS)一个或多个运行在内网的服务器或者PC运行客户端(NPC)1.2 特点Go语言编写支持跨平台支持多种协议的代理web管理端1.3 使用方法https://github.com/ehang-io/nps/releasesNPS安装配置找到自己服务器相应版本的server: cd ~ wget https://github.com/cnlh/nps/releases/download/v0.23.2/linux_amd64_server.tar.gz tar xzvf linux_amd64_server.tar.gz cd ~/nps在nps目录下面会有一个nps可执行文件、conf配置目录和web网页目录,我们只需要修改conf/nps.conf即可:vim conf/nps.conf需要改一下#web下面的几个参数,web_host= 服务器IP或者域名 web_username= admin(登录用户名) web_password= 你的密码 web_port=8080(web管理端口)修改#bridge 可以更改 NPC的连接端口。比如我们拿到一台权限受限的服务器,有防火墙,可能只有部分端口(80,443)可以出网,就需要修改成出网端口。##bridge bridge_type=tcp bridge_port=443 # 修改连接端口 bridge_ip=0.0.0.0启动#Mac/Linux ./nps test|start|stop|restart|status 测试配置文件|启动|停止|重启|状态 #Windows nps.exe test|start|stop|restart|status 测试配置文件|启动|停止|重启|状态NPC./npc -server=你的IP:8024 -vkey=唯一验证密码 -type=tcp新建好客户端后,也可以在+中看到,详细的客户端连接命令:web管理端在客户端界面可以通过新增的方式添加客户端连接,每一个连接的vkey都是唯一区分的。每一个客户端,在建立连接后,都可以建立多个不同协议的隧道,这一个个隧道就是不同的代理了。通过不同的协议和端口就可以连接代理的内网机器。frp2.1 简介frp 是一个专注于内网穿透的高性能的反向代理应用,支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。2.2 特点客户端服务端通信支持 TCP、KCP 以及 Websocket 等多种协议。端口复用,多个服务通过同一个服务端端口暴露。跨平台,但是支持的比nps少一点多种插件,提供很多功能2.3 使用方法下载:https://github.com/fatedier/frp/releases以下内容摘自:https://segmentfault.com/a/11900000218768361. 通过 rdp 访问家里的机器1.修改 frps.ini 文件,为了安全起见,这里最好配置一下身份验证,服务端和客户端的 common 配置中的 token 参数一致则身份验证通过:# frps.ini [common] bind_port = 7000 # 用于身份验证,请自行修改,要保证服务端与客户端一致 token = abcdefgh启动 frps:./frps -c ./frps.ini修改 frpc.ini 文件,假设 frps 所在服务器的公网 IP 为 x.x.x.x:# frpc.ini [common] server_addr = x.x.x.x server_port = 7000 # 用于身份验证,请自行修改,要保证服务端与客户端一致 token = abcdefgh [rdp] type = tcp local_ip = 127.0.0.1 local_port = 3389 remote_port = 6000启动 frpc:./frpc -c ./frpc.ini5.通过 rdp 访问远程的机器,地址为:x.x.x.x:6000开机自启针对 Windows 系统,为了便于使用,可以配置一下开机的时候静默启动。1.在 frpc.exe 的同级目录创建一个 start_frpc.vbs:'start_frpc.vbs '请根据实际情况修改路径 CreateObject("WScript.Shell").Run """D:\Program Files\frp_windows_amd64\frpc.exe""" & "-c" & """D:\Program Files\frp_windows_amd64\frpc.ini""",02.复制 start_frpc.vbs 文件,打开以下目录,注意将<USER_NAME>改为你的用户名:C:\Users\<USER_NAME>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup3.鼠标右击,粘贴为快捷方式即可。通过 SSH 访问公司内网机器frps 的部署步骤同上。5.启动 frpc,配置如下: # frpc.ini [common] server_addr = x.x.x.x server_port = 7000 # 用于身份验证,请自行修改,要保证服务端与客户端一致 token = abcdefgh [ssh] type = tcp local_ip = 127.0.0.1 local_port = 22 remote_port = 6000 6.通过 SSH 访问内网机器,假设用户名为 test:ssh -oPort=6000 test@x.x.x.x通过自定义域名访问部署于内网的 Web 服务有时想要让其他人通过域名访问或者测试我们在本地搭建的 Web 服务,但是由于本地机器没有公网 IP,无法将域名解析到本地的机器,通过 frp 就可以实现这一功能,以下示例为 http 服务,https 服务配置方法相同, vhost_http_port 替换为 vhost_https_port, type 设置为 https 即可。8.修改 frps.ini 文件,设置 http 访问端口为 8080:# frps.ini [common] bind_port = 7000 vhost_http_port = 8080 # 用于身份验证,请自行修改,要保证服务端与客户端一致 token = abcdefgh9.启动 frps:./frps -c ./frps.ini10.修改 frpc.ini 文件,假设 frps 所在的服务器的 IP 为 x.x.x.x,local_port 为本地机器上 Web 服务对应的端口, 绑定自定义域名 www.yourdomain.com:# frpc.ini [common] server_addr = x.x.x.x server_port = 7000 # 用于身份验证,请自行修改,要保证服务端与客户端一致 token = abcdefgh [web] type = http local_port = 80 custom_domains = www.yourdomain.com11.启动 frpc:./frpc -c ./frpc.ini12.将 www.yourdomain.com 的域名 A 记录解析到 IP x.x.x.x,如果服务器已经有对应的域名,也可以将 CNAME 记录解析到服务器原先的域名。13.通过浏览器访问 http://www.yourdomain.com:8080 即可访问到处于内网机器上的 Web 服务。 对外提供简单的文件访问服务通过 static_file 插件可以对外提供一个简单的基于 HTTP 的文件访问服务。frps 的部署步骤同上。rps 的部署步骤同上。1.启动 frpc,启用 static_file 插件,配置如下:# frpc.ini [common] server_addr = x.x.x.x server_port = 7000 # 用于身份验证,请自行修改,要保证服务端与客户端一致 token = abcdefgh [test_static_file] type = tcp remote_port = 6000 plugin = static_file # 要对外暴露的文件目录 plugin_local_path = /tmp/file # 访问 url 中会被去除的前缀,保留的内容即为要访问的文件路径 plugin_strip_prefix = static plugin_http_user = abc plugin_http_passwd = abc2.通过浏览器访问 http://x.x.x.x:6000/static/ 来查看位于 /tmp/file 目录下的文件,会要求输入已设置好的用户名和密码。常用功能统计面板(Dashboard)通过浏览器查看 frp 的状态以及代理统计信息展示。注:Dashboard 尚未针对大量的 proxy 数据展示做优化,如果出现 Dashboard 访问较慢的情况,请不要启用此功能。需要在 frps.ini 中指定 dashboard 服务使用的端口,即可开启此功能:[common] dashboard_port = 7500 # dashboard 用户名密码,默认都为 admin dashboard_user = admin dashboard_pwd = admin打开浏览器通过 http://[server_addr]:7500 访问 dashboard 界面,用户名密码默认为 admin。加密与压缩这两个功能默认是不开启的,需要在 frpc.ini 中通过配置来为指定的代理启用加密与压缩的功能,压缩算法使用 snappy:# frpc.ini [ssh] type = tcp local_port = 22 remote_port = 6000 use_encryption = true use_compression = true如果公司内网防火墙对外网访问进行了流量识别与屏蔽,例如禁止了 SSH 协议等,通过设置 use_encryption = true,将 frpc 与 frps 之间的通信内容加密传输,将会有效防止流量被拦截。如果传输的报文长度较长,通过设置 use_compression = true 对传输内容进行压缩,可以有效减小 frpc 与 frps 之间的网络流量,加快流量转发速度,但是会额外消耗一些 CPU 资源。[TLS从 v0.25.0 版本开始 frpc 和 frps 之间支持通过 TLS 协议加密传输。通过在 frpc.ini 的 common 中配置 tls_enable = true 来启用此功能,安全性更高。为了端口复用,frp 建立 TLS 连接的第一个字节为 0x17。注意:启用此功能后除 xtcp 外,不需要再设置 use_encryption。代理限速目前支持在客户端的代理配置中设置代理级别的限速,限制单个 proxy 可以占用的带宽。# frpc.ini [ssh] type = tcp local_port = 22 remote_port = 6000 bandwidth_limit = 1MB在代理配置中增加 bandwidth_limit 字段启用此功能,目前仅支持 MB 和 KB 单位。范围端口映射在 frpc 的配置文件中可以指定映射多个端口,目前只支持 tcp 和 udp 的类型。这一功能通过 range: 段落标记来实现,客户端会解析这个标记中的配置,将其拆分成多个 proxy,每一个 proxy 以数字为后缀命名。例如要映射本地 6000-6005, 6007 这 6 个端口,主要配置如下:# frpc.ini [range:test_tcp] type = tcp local_ip = 127.0.0.1 local_port = 6000-6006,6007 remote_port = 6000-6006,6007实际连接成功后会创建 8 个 proxy,命名为 test_tcp_0, test_tcp_1 ... test_tcp_7。ew3.1 简介EW 是一套便携式的网络穿透工具,具有 SOCKS v5服务架设和端口转发两大核心功能,可在复杂网络环境下完成网络穿透。但是,现在工具已经不更新了。。。3.2 特点轻量级,C语言编写可以设置多级代理跨平台但是只支持Socks代理3.3 使用方法以下使用方法均摘自:http://rootkiter.com/EarthWorm/以下所有样例,如无特殊说明代理端口均为1080,服务均为SOCKSv5代理服务.该工具共有 6 种命令格式(ssocksd、rcsocks、rssocks、lcx_slave、lcx_listen、lcx_tran)。正向 SOCKS v5 服务器$ ./ew -s ssocksd -l 1080反弹 SOCKS v5 服务器这个操作具体分两步:a) 先在一台具有公网 ip 的主机A上运行以下命令:$ ./ew -s rcsocks -l 1080 -e 8888b) 在目标主机B上启动 SOCKS v5 服务 并反弹到公网主机的 8888端口$ ./ew -s rssocks -d 1.1.1.1 -e 8888成功。多级级联工具中自带的三条端口转发指令, 它们的参数格式分别为:$ ./ew -s lcx_listen -l 1080 -e 8888 $ ./ew -s lcx_tran -l 1080 -f 2.2.2.3 -g 9999 $ ./ew -s lcx_slave -d 1.1.1.1 -e 8888 -f 2.2.2.3 -g 9999通过这些端口转发指令可以将处于网络深层的基于TCP的服务转发至根前,比如 SOCKS v5。首先提供两个“二级级联”本地SOCKS测试样例:a) lcx_tran 的用法$ ./ew -s ssocksd -l 9999$ ./ew -s lcx_tran -l 1080 -f 127.0.0.1 -g 9999b) lcx_listen、lcx_slave 的用法$ ./ew -s lcx_listen -l 1080 -e 8888$ ./ew -s ssocksd -l 9999$ ./ew -s lcx_slave -d 127.0.0.1 -e 8888 -f 127.0.0.1 -g 9999再提供一个“三级级联”的本地SOCKS测试用例以供参考$ ./ew -s rcsocks -l 1080 -e 8888$ ./ew -s lcx_slave -d 127.0.0.1 -e 8888 -f 127.0.0.1 -g 9999$ ./ew -s lcx_listen -l 9999 -e 7777$ ./ew -s rssocks -d 127.0.0.1 -e 7777数据流向: SOCKS v5 -> 1080 -> 8888 -> 9999 -> 7777 -> rssocksngrok4.1 简介ngrok 是一个反向代理,通过在公共端点和本地运行的 Web 服务器之间建立一个安全的通道,实现内网主机的服务可以暴露给外网。ngrok 可捕获和分析所有通道上的流量,便于后期分析和重放,所以ngrok可以很方便地协助服务端程序测试。4.2 特点官方维护,一般较为稳定跨平台,闭源有流量记录和重发功能4.3 使用方法进入ngrok官网(https://ngrok.com/),注册ngrok账号并下载ngrok;根据官网给定的授权码,运行如下授权命令;./ngrok authtoken 1hAotxhmORtzCYvUc3BsxDBPh1H_**./ngrok http 80即可将机器的80端口http服务暴露到公网,并且会提供一个公网域名。可以通过官网的UI界面查看数据包和流量等等(但是要付费==、)还可以通过一些命令将内网的文件和其他TCP服务 暴露到公网中。有授权的设置文件共享ngrok http -auth="user:password" file:///Users/alan/share无授权的设置文件共享ngrok http "file:///C:\Users\alan\Public Folder"将主机的3389的TCP端口暴露到公网ngrok tcp 3389更多使用方法参考:https://ngrok.com/docs来自微信
2025年08月28日
1 阅读
0 评论
0 点赞
2025-08-27
C++ 类的构造函数和析构函数
类的构造函数类的构造函数是类的一种特殊的成员函数,它会在每次创建类的新对象时执行。构造函数的名称与类的名称是完全相同的,并且不会返回任何类型,也不会返回 void。构造函数可用于为某些成员变量设置初始值。下面的实例有助于更好地理解构造函数的概念:实例 #include <iostream> using namespace std; class Line { public: void setLength( double len ); double getLength( void ); Line(); // 这是构造函数 private: double length; }; // 成员函数定义,包括构造函数 Line::Line(void) { cout << "Object is being created" << endl; } void Line::setLength( double len ) { length = len; } double Line::getLength( void ) { return length; } // 程序的主函数 int main( ) { Line line; // 设置长度 line.setLength(6.0); cout << "Length of line : " << line.getLength() <<endl; return 0; } 当上面的代码被编译和执行时,它会产生下列结果:Object is being createdLength of line : 6带参数的构造函数默认的构造函数没有任何参数,但如果需要,构造函数也可以带有参数。这样在创建对象时就会给对象赋初始值,如下面的例子所示:实例 #include <iostream> using namespace std; class Line { public: void setLength( double len ); double getLength( void ); Line(double len); // 这是构造函数 private: double length; }; // 成员函数定义,包括构造函数 Line::Line( double len) { cout << "Object is being created, length = " << len << endl; length = len; } void Line::setLength( double len ) { length = len; } double Line::getLength( void ) { return length; } // 程序的主函数 int main( ) { Line line(10.0); // 获取默认设置的长度 cout << "Length of line : " << line.getLength() <<endl; // 再次设置长度 line.setLength(6.0); cout << "Length of line : " << line.getLength() <<endl; return 0; } 当上面的代码被编译和执行时,它会产生下列结果:Object is being created, length = 10Length of line : 10Length of line : 6使用初始化列表来初始化字段使用初始化列表来初始化字段: Line::Line( double len): length(len) { cout << "Object is being created, length = " << len << endl; } 上面的语法等同于如下语法: Line::Line( double len) { length = len; cout << "Object is being created, length = " << len << endl; } 假设有一个类 C,具有多个字段 X、Y、Z 等需要进行初始化,同理地,您可以使用上面的语法,只需要在不同的字段使用逗号进行分隔,如下所示: C::C( double a, double b, double c): X(a), Y(b), Z(c) { .... } 类的析构函数类的析构函数是类的一种特殊的成员函数,它会在每次删除所创建的对象时执行。析构函数的名称与类的名称是完全相同的,只是在前面加了个波浪号(~)作为前缀,它不会返回任何值,也不能带有任何参数。析构函数有助于在跳出程序(比如关闭文件、释放内存等)前释放资源。下面的实例有助于更好地理解析构函数的概念:实例 #include <iostream> using namespace std; class Line { public: void setLength( double len ); double getLength( void ); Line(); // 这是构造函数声明 ~Line(); // 这是析构函数声明 private: double length; }; // 成员函数定义,包括构造函数 Line::Line(void) { cout << "Object is being created" << endl; } Line::~Line(void) { cout << "Object is being deleted" << endl; } void Line::setLength( double len ) { length = len; } double Line::getLength( void ) { return length; } // 程序的主函数 int main( ) { Line line; // 设置长度 line.setLength(6.0); cout << "Length of line : " << line.getLength() <<endl; return 0; } 当上面的代码被编译和执行时,它会产生下列结果:Object is being createdLength of line : 6Object is being deleted为什么C++的构造函数在class new 的就自动执行呢?在C++中,构造函数在对象创建时自动执行的设计是语言的核心特性,其背后蕴含着深刻的工程哲学和系统设计思想。以下是结构化解析:内存分配与构造分离new操作符实际执行两个独立操作:MyClass* obj = new MyClass(); // 等价于: void* mem = operator new(sizeof(MyClass)); // 1. 仅分配原始内存 MyClass* obj = new(mem) MyClass(); // 2. 在内存地址调用构造函数构造函数的本质编译器将构造函数视为类型初始化器:编译期在所有对象创建点自动插入构造函数调用构造函数签名经特殊处理(如添加隐式this指针参数)设计哲学解析一、对象生命周期完整性保障阶段 自动行为 意义创建期 构造自动执行 确保对象从诞生起就处于有效状态生存期 方法手动调用 赋予开发者控制权销毁期 析构自动执行 防止资源泄漏(RAII核心)二、类型系统安全的基石class Database { public: Database() { connect("default_server"); } // 强制初始化 }; // 若不自动构造: Database* db = (Database*)malloc(sizeof(Database)); db->query("SELECT..."); // 崩溃!未初始化的连接三、面向对象范式的实现基础继承链构造:自动按顺序调用基类构造函数class Base { Base() {/*基类初始化*/} }; class Derived : public Base { Derived() : Base() {/*编译器自动插入基类构造*/} };成员初始化:按声明顺序自动构造成员对象💡 关键优势分析防御性编程强化class File { HANDLE hFile; public: File(const char* name) : hFile(OpenFile(name)) { if(!hFile) throw "打开失败"; // 创建即验证 } }; // 使用时无法绕过验证 File log("data.bin"); // 要么有效对象,要么异常设计权衡与边界与C语言的本质区别🌟 总结:自动构造的核心价值安全屏障:消除未初始化对象风险范式实现:支撑RAII/异常安全等核心特性系统契约:对象诞生即满足类不变式(class invariant)工程效率:减少样板代码(对比C的手动初始化)类型完备:实现真正意义上的抽象数据类型(ADT)正如C++之父Bjarne Stroustrup所言:“构造函数不是可选的——它们定义了对象存在的意义”。这种设计强制保证了对象语义完整性,是C++类型安全的基石。怎么判断储C++的class 内部的function哪一个是构造函数,哪一个是析构函数在C++中,构造函数和析构函数有明确的语法特征和功能定位。以下是简明清晰的判断指南:🔍 构造函数识别特征命名规则函数名 必须与类名完全相同(大小写敏感)class MyClass { public: MyClass(); // ✅ 构造函数 };无返回类型不声明任何返回类型(连 void 都不需要)class Student { public: Student(string name); // ✅ 构造(无返回类型) void setGrade(); // ❌ 普通方法(有void) };可重载特性一个类可以有 多个构造函数(参数列表不同)class Point { public: Point(); // ✅ 默认构造 Point(int x, int y); // ✅ 带参构造 };析构函数识别特征命名规则函数名 必须是 ~类名(波浪号前缀)class Database { public: ~Database(); // ✅ 析构函数 };无参数无返回值严格无参数,且不声明返回类型class FileHandler { public: ~FileHandler(); // ✅ 正确形式 ~FileHandler(int); // ❌ 错误(不可带参数) };唯一性每个类 有且仅有一个 析构函数(不可重载)遇到类成员函数时问:是否与类名同名? → 构造函数候选是否带波浪号前缀? → 析构函数候选是否有返回类型? → 普通方法(非构造/析构)析构函数带参数? → 语法错误(必须无参)掌握这些规则后,您能瞬间识别任何C++类中的构造/析构函数。这种设计确保对象 诞生即初始化(构造),消亡即清理(析构),是C++资源管理的基石 💪。特殊场景辨析默认构造无参数的构造函数(编译器自动生成若未定义)class Widget { public: Widget(); // 显式默认构造 // 若未声明,编译器生成隐式默认构造虚析构函数(多态基类必备)class Shape { public: virtual ~Shape(); // ✅ 虚析构(允许派生类正确释放) };.
2025年08月27日
0 阅读
0 评论
0 点赞
1
...
14
15
16
...
76