当前位置: 首页 > news >正文

Maven构建OSGI+HttpServer应用

Maven构建OSGI+HttpServer应用

官网(https://eclipse.dev/equinox/server/http_in_equinox.php)介绍有两种方式:

一种是基于”org.eclipse.equinox.http”包的轻量级实现,另一种是基于”org.eclipse.equinox.http.jetty”包(基于jetty的Servlet)实现。

使用 "org.eclipse.equinox.http" 包(例如:http-1.0.100-v20070423.jar),可以将我们自定义的服务(servlet或静态资源页面)注册到这个 HttpService 中去,实现自定义的HTTP服务。

"org.osgi.service.http" 包(例如:org.osgi.service.http-1.2.2.jar)内部会内嵌一个 HttpService Interface,而"org.eclipse.equinox.http" 包(http-1.0.100-v20070423.jar)提供了一个上述Interface的 HttpService实现类,因此,一旦这个osgi bundle (http-1.0.100-v20070423.jar)启动了,就会有一个内嵌的 http 服务被启动,默认地址是 http://localhost,端口为 80,可以通过指定参数 “org.osgi.service.http.port”来修改默认端口。

"org.eclipse.equinox.http" 包(http-1.0.100-v20070423.jar)内有一个上面那个 HttpService Interface 的实现类:

想要提供我们自定义的 HttpService服务,就要将我们的服务(servlet或静态资源页面)注册到这个 HttpService 中去,需要用到 "org.osgi.service.http" 包中的 HttpService 类的两个注册方法:

1)注册静态资源:
registerResources(String alias, String name, HttpContext httpContext)

2)注册 Servlet 类:
registerServlet(String alias, Servlet servlet, Dictionary initparams, HttpContext httpContext)

所以要想提供我自己的WebService实现,我们就需要:

提供自定义的WebService实现的步骤如下:
1)获取 httpService 对象;
2)编码提供 servlet 和 webpage 的实现;
3)将 servlet 和 webpage 注册到 HttpService 服务中去(同时指定对应的 alias);
4)访问;

新建manve项目:

创建package、class、和编码:
1)Java package:com.xxx.osgi.httpserver.demo、com.xxx.osgi.httpserver.servlet
2)Java class文件:Activator.java、MyServlet.java

Activator.java:

package com.xxx.osgi.httpserver.demo;import com.xxx.osgi.httpserver.servlet.MyServlet;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.HttpService;import java.util.LinkedList;
import java.util.List;/*** @author Frank* @date 2023/12/26*/
public class Activator implements BundleActivator {private static BundleContext bundleContext;private HttpService httpService;private List<Bundle> bundles;static BundleContext getBundleContext() {return bundleContext;}public void start(BundleContext bundleContext) throws Exception {Activator.bundleContext = bundleContext;installBundles(bundleContext, false); // install other bundlesServiceReference serviceReference = bundleContext.getServiceReference(HttpService.class.getName());httpService = (HttpService) bundleContext.getService(serviceReference);// 注册HttpContext httpContext = httpService.createDefaultHttpContext();// 注册静态页面,设置别名"/osgi",所有对"/osgi"的请求映射到"/webpage/index.html"httpService.registerResources("/osgi", "/webpage/index.html", httpContext);System.out.println("start ok");// 注册 servlet,设置servlet别名"/test",所有对'/test"的请求映射到myServlet的实现MyServlet myServlet = new MyServlet();httpService.registerServlet("/test", myServlet, null, httpContext);}public void stop(BundleContext bundleContext) throws Exception {installBundles(bundleContext, true); //uninstall other bundleshttpService.unregister("/osgi");httpService.unregister("/test");Activator.bundleContext = null;System.out.println("stop ok");}public void installBundles(BundleContext context, boolean uninstall) {List<String> bundleFiles = new LinkedList<String>();List<Bundle> installedBundles = new LinkedList<Bundle>();//install my other bundles// System.out.printf("1 %s\n", FileLocator.getBundleFile(FrameworkUtil.getBundle(Activator.class)).getAbsolutePath());// System.out.printf("2 %s\n", FileLocator.getBundleFile(context.getBundle()).getAbsolutePath());// System.out.printf("3 %s\n", context.getBundle().getLocation());// String baseDir = FileLocator.getBundleFile(context.getBundle()).getParentFile().getAbsolutePath();String baseDir = context.getBundle().getLocation().replaceFirst("/[^/]*.jar","/");bundleFiles.add(baseDir + "helloworld-server-1.0.0-SNAPSHOT.jar");if (!uninstall) {// install & start bundlesfor (String bundleFile : bundleFiles) {try {Bundle bundle = context.installBundle(bundleFile);installedBundles.add(bundle);bundle.start();} catch (BundleException e) {if (!e.getMessage().contains("A bundle is already installed")) {throw new RuntimeException(e);}}}bundles = installedBundles;System.out.printf("all bundles (cnt = %d) installed and started!", bundles.size());} else {// stop & uninstall bundlesfor (Bundle bundle : bundles) {try {context.getBundle(bundle.getBundleId()).stop();context.getBundle(bundle.getBundleId()).uninstall();} catch (BundleException e) {throw new RuntimeException(e);}}System.out.printf("all bundles (cnt = %d) stopped and uninstalled!", bundles.size());}}
}

MyServlet.java:

package com.xxx.osgi.httpserver.servlet;import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.logging.Logger;public class MyServlet extends HttpServlet implements Servlet {private Logger logger = Logger.getLogger(this.getClass().getName());@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write("MyServlet return: Method=" + req.getMethod() + ", URI=" + req.getRequestURI());}@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write("MyServlet return: Method=" + req.getMethod() + ", URI=" + req.getRequestURI());}
}

3)创建静态页面文件:webpage/index.html

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>jetty test</title>
</head>
<body>
<h2>OSGI HttpServer/Jetty Test</h2>
<font color="green"> register static resource/pages: </font><br>
registerResources(String alias, String name, HttpContext httpContext) <br><br><font color="green">register servlet class: </font><br>
registerServlet(String alias, Servlet servlet, Dictionary initparams, HttpContext httpContext)
</body>
</html>

4)创建&编辑 pom.xml 文件

pom文件中定义了OSGI框架和版本、编码中所需的依赖以及osgi menifest和osgi打包配置:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.xxx.osgi</groupId><artifactId>osgi-httpserver-demo</artifactId><version>1.0.0-SNAPSHOT</version><packaging>bundle</packaging><name>osgi-httpserver-demo</name><url>http://maven.apache.org</url><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.8</java.version><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><dependency><!-- 该版本 maven 仓库找不到,如果要用该版本可以在 Project Structure->Project Settings->Modules 中设置:--><!-- 设置 OSGI:General->Configure OSGI Core Library->Use Library 指定本地 jar 文件静态添加 osgi lib  --><!--<groupId>org.eclipse</groupId><artifactId>osgi</artifactId><version>3.18.600.v20231110-1900</version><scope>provided</scope>--><!-- 该版本maven仓库可以找到,可以用这个版本。在 pom 中指定 osgi lib 的 dependency 依赖 --><groupId>org.eclipse</groupId><artifactId>osgi</artifactId><version>3.10.0-v20140606-1445</version><scope>provided</scope></dependency><!-- START: httpServer required bundles --><!-- org.osgi.service.cm_1.6.1.202109301733.jar --><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.service.cm</artifactId><version>1.6.1</version></dependency><!-- javax.servlet-3.0.0.v201112011016.jar --><dependency><groupId>org.eclipse.jetty.orbit</groupId><artifactId>javax.servlet</artifactId><version>3.0.0.v201112011016</version></dependency><!-- http-1.0.100-v20070423.jar --><dependency><groupId>org.eclipse.equinox</groupId><artifactId>http</artifactId><version>1.0.100-v20070423</version></dependency><!-- org.osgi.service.http-1.2.2.jar --><dependency><groupId>org.osgi</groupId><artifactId>org.osgi.service.http</artifactId><version>1.2.2</version></dependency><!-- END: httpServer required bundles --><!-- for: org.eclipse.core.runtime.FileLocator --><!-- common-3.6.200-v20130402-1505.jar / org.eclipse.equinox.common.source_3.18.200.v20231106-1826.jar --><dependency><groupId>org.eclipse.equinox</groupId><artifactId>common</artifactId><version>3.6.200-v20130402-1505</version></dependency></dependencies><build><plugins><plugin><!-- osgi 打包配置,使用 maven-bundle-plugin 插件进行 osgi 打包 bundle jar --><!-- 使用maven-bundle-plugin打包方式时指定manifest文件不生效,但可在 instructions 中配置 manifest 参数 --><groupId>org.apache.felix</groupId><artifactId>maven-bundle-plugin</artifactId><version>3.5.0</version><extensions>true</extensions><configuration><instructions><!-- 把依赖的普通jar和bundle jar也一起打包进去(/lib目录下),bundle jar 服务依赖还要在 Import-Package 中指定 --><Embed-Dependency>*;scope=compile|runtime</Embed-Dependency><Embed-Directory>lib</Embed-Directory><Embed-Transitive>true</Embed-Transitive><!-- BEGIN: 把本地静态资源目录也打包进去 --><Include-Resource>webpage=webpage</Include-Resource><!-- END: 把本地静态资源目录webpage也打包进去(到webpage目录、相当于目录拷贝) --><Bundle-ClassPath>.,{maven-dependencies}</Bundle-ClassPath><Bundle-Name>${project.name}</Bundle-Name><Bundle-SymbolicName>$(replace;${project.artifactId};-;_)</Bundle-SymbolicName><Bundle-Version>${project.version}</Bundle-Version><Bundle-Activator>com.xxx.osgi.httpserver.demo.Activator</Bundle-Activator><DynamicImport-Package>*</DynamicImport-Package><Import-Package>javax.servlet,javax.servlet.http,org.osgi.service.http;resolution:="optional"</Import-Package><Export-Package></Export-Package></instructions></configuration></plugin></plugins></build>
</project>

整体项目的代码结构如下:

准备运行依赖的bundles:

org.osgi.service.cm_1.6.1.202109301733.jar
javax.servlet-3.0.0.v201112011016.jar
org.osgi.service.http-1.2.2.jar
http-1.0.100-v20070423.jar
 

直接在 configuration/config.ini 初始化启动配置中加入依赖 bundles 或者启动 osgi 以后执行 install 安装依赖 bundles:
install plugins/org.osgi.service.cm_1.6.1.202109301733.jar
install other_bundles/javax.servlet-3.0.0.v201112011016.jar
install other_bundles/org.osgi.service.http-1.2.2.jar
install other_bundles/http-1.0.100-v20070423.jar
start 5 6 7 8 

注意,多条命名install时有先后顺序依赖,也可以放在一条命令执行多个 bundle 的install(无顺序依赖)
install plugins/org.osgi.service.cm_1.6.1.202109301733.jar other_bundles/javax.servlet-3.0.0.v201112011016.jar other_bundles/org.osgi.service.http-1.2.2.jar other_bundles/http-1.0.100-v20070423.jar
 

“org.osgi.service.http”的HttpService Interface的实现类bundle “org.eclipse.equinox.http”启动后,HttpService服务就启动了、查看HttpService监听端口已开启(如果equinox的配置文件或启动参数没有指定 org.osgi.service.http.port=8080 的话,默认是监听的是 80 端口):

项目编译打包:
执行命令打包
mvn clean package

拷贝项目编译打包生成的jar文件到osgi运行环境:

执行osgi-httpserver-demo jar包(install & start):

项目bundle 9已经启动、bundle9内代码install & start 的其他bundel 10 也都start成功,状态为ACTIVE了。

httpServer 访问测试(访问 localhost:8080/osgi 和 localhost:8080/test):
命令行访问页面:

浏览器访问页面:

相关文章:

Maven构建OSGI+HttpServer应用

Maven构建OSGIHttpServer应用 官网&#xff08;https://eclipse.dev/equinox/server/http_in_equinox.php&#xff09;介绍有两种方式&#xff1a; 一种是基于”org.eclipse.equinox.http”包的轻量级实现&#xff0c;另一种是基于”org.eclipse.equinox.http.jetty”包&#…...

chrome扩展插件常用文件及作用

Chrome扩展通常包含以下常用文件及其作用&#xff1a; manifest.json&#xff1a; 描述了扩展的基本信息&#xff0c;如名称、版本、权限、图标等。定义了扩展的各种组件和功能&#xff0c;包括后台脚本、内容脚本、页面、浏览器动作按钮等。 background.js&#xff1a; 后台脚…...

PdfFactory Pro软件下载以及序列号注册码生成器

PdfFactory Pro注册机是一款针对同名虚拟打印机软件所推出的用户名和序列号生成器。PdfFactory Pro是一款非常专业的PDF虚拟打印软件&#xff0c;通过使用这款注册机&#xff0c;就能帮助用户免费获取注册码&#xff0c;一键激活&#xff0c;永久免费使用。 pdffactory7注册码如…...

jsp康养小镇管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP康养小镇管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql5.0&a…...

Android 无操作之后定时退出

android定时器监用户听对页面无操作5分钟退出登录实现 - 简书 private long advertisingTime 600000;///定时结束退出登录10分(分钟)600000毫秒public CountDownTimer countDownTimer;Overrideprotected void onResume() {super.onResume();//启动定时if (isTimedExitApp()) …...

CMS 检测神器:CMSeek 保姆级教程(附链接)

一、介绍 CMSeek&#xff08;Content Management System Exploitation and Enumeration Toolkit&#xff09;是一款用于检测和利用网站上可能存在的内容管理系统&#xff08;CMS&#xff09;漏洞的开源工具。它旨在帮助安全研究人员和渗透测试人员识别目标网站所使用的CMS&…...

oracle 启动命令以及ORA-01033问题处理、删除归档日志

1 启动数据库:startup 2 关闭数据库&#xff1a;Shutdown immediate 3 查看监听状态&#xff1a;lsnrctl status 4 启动监听&#xff1a;lsnrctl start 5 停止监听&#xff1a;lsnrctl stop 常见问题 1、在服务器重启后会出现&#xff0c;Oracle ORA-01033: ORAC…...

【大模型上下文长度扩展】MedGPT:解决遗忘 + 永久记忆 + 无限上下文

MedGPT&#xff1a;解决遗忘 永久记忆 无限上下文 问题&#xff1a;如何提升语言模型在长对话中的记忆和处理能力&#xff1f;子问题1&#xff1a;有限上下文窗口的限制子问题2&#xff1a;复杂文档处理的挑战子问题3&#xff1a;长期记忆的维护子问题4&#xff1a;即时信息检…...

谷歌seo搜索引擎优化有什么思路?

正常做seo哪有那么多思路&#xff0c;其实就那么几种方法&#xff0c;无非就关键词&#xff0c;站内优化&#xff0c;外链&#xff0c;可以说万变不离其宗&#xff0c;但如果交给我们&#xff0c;你就可以实现其他的思路&#xff0c;或者说玩法 收录可以说是一个网站的基础&…...

腾讯云与IBM共同打造“高性能计算服务解决方案“

腾讯云与IBM共同打造"高性能计算服务解决方案" 腾讯云与IBM达成战略合作&#xff0c;对优势产品及服务进行深度集成&#xff0c;基于腾讯云产品及服务&#xff0c;共同打造"腾讯-IBM混合云与人工智能解决方案"。双方通过更为紧密的嵌入式解决方案的深度合…...

【SparkML实践7】特征选择器FeatureSelector

本节介绍了用于处理特征的算法&#xff0c;大致可以分为以下几组&#xff1a; 提取&#xff08;Extraction&#xff09;&#xff1a;从“原始”数据中提取特征。转换&#xff08;Transformation&#xff09;&#xff1a;缩放、转换或修改特征。选择&#xff08;Selection&…...

LeetCode983. Minimum Cost For Tickets——动态规划

文章目录 一、题目二、题解 一、题目 You have planned some train traveling one year in advance. The days of the year in which you will travel are given as an integer array days. Each day is an integer from 1 to 365. Train tickets are sold in three differen…...

百卓Smart管理平台 uploadfile.php 文件上传漏洞【CVE-2024-0939】

百卓Smart管理平台 uploadfile.php 文件上传漏洞【CVE-2024-0939】 一、 产品简介二、 漏洞概述三、 影响范围四、 复现环境五、 漏洞复现手动复现小龙验证Goby验证 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工…...

项目中常用的一些数据库及缓存

1、常见的开发工具介绍 MySQL: MySQL是一种流行的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;由瑞典MySQL AB公司开发&#xff0c;并在后来被Sun Microsystems收购&#xff0c;最终成为Oracle公司的一部分。MySQL广泛用于各种Web应用程序和大型企业应…...

MoE-LLaVA:具有高效缩放和多模态专业知识的大型视觉语言模型

视觉和语言模型的交叉导致了人工智能的变革性进步&#xff0c;使应用程序能够以类似于人类感知的方式理解和解释世界。大型视觉语言模型(LVLMs)在图像识别、视觉问题回答和多模态交互方面提供了无与伦比的能力。 MoE-LLaVA利用了“专家混合”策略融合视觉和语言数据&#xff0…...

【Java】ArrayList和LinkedList的区别是什么

目录 1. 数据结构 2. 性能特点 3. 源码分析 4. 代码演示 5. 细节和使用场景 ArrayList 和 LinkedList 分别代表了两类不同的数据结构&#xff1a;动态数组和链表。它们都实现了 Java 的 List 接口&#xff0c;但是有着各自独特的特点和性能表现。 1. 数据结构 ArrayList…...

RabbitMQ-4.MQ的可靠性

MQ的可靠性 4.MQ的可靠性4.1.数据持久化4.1.1.交换机持久化4.1.2.队列持久化4.1.3.消息持久化 4.2.LazyQueue4.2.1.控制台配置Lazy模式4.2.2.代码配置Lazy模式4.2.3.更新已有队列为lazy模式 4.MQ的可靠性 消息到达MQ以后&#xff0c;如果MQ不能及时保存&#xff0c;也会导致消…...

编程相关的经典的网站和书籍

经典网站&#xff1a; Stack Overflow&#xff1a;作为全球最大的程序员问答社区&#xff0c;Stack Overflow 汇聚了大量的编程问题和解答&#xff0c;为程序员提供了极大的帮助。GitHub&#xff1a;全球最大的开源代码托管平台&#xff0c;程序员可以在上面共享自己的项目代码…...

Java代码实现基数排序算法(附带源码)

基数排序是一种非比较型整数排序算法&#xff0c;其原理是将整数按位数切割成不同的数字&#xff0c;然后按每个位数分别比较。由于整数也可以表达字符串&#xff08;比如名字或日期&#xff09;和特定格式的浮点数&#xff0c;所以基数排序也不是只能使用于整数。 1. 基数排序…...

基于python+django,我开发了一款药店信息管理系统

功能介绍 平台采用B/S结构&#xff0c;后端采用主流的Python语言进行开发&#xff0c;前端采用主流的Vue.js进行开发。 功能包括&#xff1a;药品管理、分类管理、顾客管理、用户管理、日志管理、系统信息模块。 代码结构 server目录是后端代码web目录是前端代码 部署运行…...

酒店门锁V10SDK接口说明-幽冥大陆(一百23)—东方仙盟

相关文件系统环境C# :NET.20,NET3.5,NET4,NET4.5,NET 5.0C:VS2005,VS2012,VS2015操作系统&#xff1a;未来之窗VOSWEB:CHROME43核心代码完整代码using System; using System.Collections.Generic; using System.Text; using System.Collections.Specialized;using System.Windo…...

零基础轻松拿捏!魔珐星云青少年健康运动教学数字人搭建全流程指南

大家好&#xff01;本次给大家分享一款面向青少年体育教育的AI创意实践项目——青少年健康运动教学智能数字交互系统。本项目聚焦青少年体质健康痛点&#xff0c;围绕体育教学智能化升级需求&#xff0c;打造集健康知识教学、运动动作陪练、健康知识考核、运动能力评测于一体的…...

对比 Token Plan 与按量计费在 Taotoken 平台上的成本体感差异

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 对比 Token Plan 与按量计费在 Taotoken 平台上的成本体感差异 对于个人开发者或项目管理者而言&#xff0c;在接入大模型服务时&a…...

照着用就行:2026 最新降AIGC软件测评与推荐

2026年真正好用的AI论文降重与改写工具&#xff0c;核心看降重效果、去AI味、格式保留、学术适配四大指标。综合实测&#xff0c;千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队&#xff0c;覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 …...

FM3773 低功耗离线式恒流/恒压 PSR 控制器

概述 FM3773 是一种高性能的交流/直流用于电池充电器和适配器的电源控制器&#xff0c;内置 850V 功率三极管。该设备采用脉冲频率调制&#xff08;PFM&#xff09;的方法来建立非连续导通模式&#xff08;DCM&#xff09;反激式电源。 FM3773 提供精确的恒定电压&#xff0c;恒…...

告别浪费!SolidWorks企业级共享方案,实现降本增效全攻略

还在为 SolidWorks 高昂的硬件投入和混乱的图纸管理头疼&#xff1f;告别“一人一机”的浪费模式&#xff0c;企业级共享方案才是降本增效的正解。这套攻略基于“1 台高性能服务器 云飞云共享云桌面”架构&#xff0c;帮你把硬件成本砍掉 60%&#xff0c;把软件利用率翻倍。一…...

【DeepSeek架构评审功能深度解密】:20年架构师亲授3大避坑指南与5步落地 checklist

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;DeepSeek架构评审功能全景概览 DeepSeek架构评审功能是一套面向大模型系统设计与工程落地的自动化分析框架&#xff0c;聚焦于模型结构合理性、计算图优化潜力、内存访问模式、算子兼容性及部署约束等多维度评…...

37家金融客户紧急启用的DeepSeek扫描辅助加固包(含未公开API调用密钥策略)

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;DeepSeek漏洞扫描辅助的背景与战略价值 近年来&#xff0c;大模型在安全领域的应用正从辅助问答向深度协同防御演进。DeepSeek系列模型凭借其开源、高推理精度及强代码理解能力&#xff0c;成为构建智能化漏洞…...

免费抓包工具选型指南:Wireshark、Fiddler、mitmproxy、Charles实战对比

1. 抓包工具不是“黑科技”&#xff0c;而是网络世界的显微镜很多人第一次听说“抓包”&#xff0c;脑子里立刻浮现出黑客电影里满屏滚动的绿色代码、键盘敲得噼啪作响、三秒破解银行防火墙的画面。其实完全不是这样——抓包&#xff08;Packet Capture&#xff09;本质上就是把…...

如何快速解锁中兴光猫权限:zteOnu工具完整使用指南

如何快速解锁中兴光猫权限&#xff1a;zteOnu工具完整使用指南 【免费下载链接】zteOnu A tool that can open ZTE onu device factory mode 项目地址: https://gitcode.com/gh_mirrors/zt/zteOnu 中兴光猫作为家庭网络的核心设备&#xff0c;其强大的硬件性能常常被默认…...