网件路由器装插件(路由器web服务器)
刚考完研究生,开始有时间写文章。复习的时候经常忍不住折腾各种东西,于是有一天看中了我手里的华为路由器。什么?华为路由器,你可能有这个疑问。华为路由器不是自研芯片吗?就像我手里的这个华为路由器,是华为自己研发的凌霄芯片。它不对外开放。怎么折腾?于是就有了下面的研究过程。
首先,你能折腾什么?就像我手里的草莓派一样,刷OpenWrt系统轻而易举。有些人可能会有一些疑问。什么是OpenWrt系统?其实这是一个开源的路由器操作系统。很多路由器系统都是在此基础上开发的,这个系统可玩性很高。但是华为路由器连固件下载都没有打开,这样折腾系统不太合适。
开发路由器插件呢?看似可行,但此时我只知道路由器插件只能在华为的专用路由器市场安装,而且路由器已经买了好几年了。插件很少,主要是IOT家电控制应用,但这条路理论上可行,所以我决定折腾路由器插件的开发。
目前华为路由器理论上支持路由器插件的开发,只要有插件应用市场,很多其他品牌的路由器也支持。不过每个路由器的开发方式都不一样,可以参考官方文档。目前我只有华为的路由器,型号是Pro2,是几年前的路由器。都下市了,固件也不更新。通过华为官网文档,我把路由器序列号发到华为的联系邮箱,等待路由器适配完成,更新固件,然后切换到调试版本。
华为运行OpenEE开发平台,插件在此基础上开发。同时路由器硬件通过OSGI接口提供对外调用能力,插件运行在JVM上。JVM?没错,就是我们Java程序员喜欢的JVM。调试版可以直接登录root用户运行的路由器后台,支持基本的Linux命令。然后我在路由器上找到了JVM,研究了一下。事实上,我研究了rt.jar的源代码,这个JVM是一个极其简化的版本。去掉了很多与路由器操作无关的类,增加了很多华为自己写的类。然而,我们编程中最常用的类仍然没有被简化。
插件开发分为前端和后端。后端可以开发基于JVM的API接口供前端调用。前端可以使用HTML等任何前端技术直接开发,但只能使用特定的函数调用后端API。最后,开发的应用可以上传到路由器上运行,应用也可以直接在路由器市场打开、运行、卸载。
可以按照官方文件操作,这里就不贴链接了。如果有开发需求,可以直接在华为开发者官网搜索路由器开发文档,也可以和我讨论。首先你需要准备好开发环境,JDK1.8和Maven基本够用,然后运行官方脚本将华为的几个Jar包导入Maven本地库。
演示项目是Maven类型的项目。熟悉Java开发的人应该熟悉,可以用自己喜欢的软件进行开发。比如我喜欢用idea做开发。执行mvn install时,生成相应的Jar包,然后由官方脚本打包成Apk文件。对,是Apk文件,但不是安卓上的Apk,而是华为路由器对应的Apk文件。然后,官方还提供了一个上传应用的工具。直接上传就行了。
就这样,一个Hello Word应用跑到了路由器上。但官方演示项目没有前端,相应的输出只能在后台控制台上查看。如果需要开发前端,需要将相应的前端文件上传到公网服务器,通过IP调用。
演示应用程序正在运行,所以我准备做下一步。由于路由器运行的是JVM,所以运行Web应用应该没有问题,而且我的路由器还有512M内存,所以低负载的Web应用应该没有问题。在这个基础上,我们可以做任何我们想做的事情,比如做NAS服务器,做内部博客服务器等等。当然,如果你有公网条件,也可以作为小型博客服务器。这里只讨论内部网应用。JDK1.8最初构建了一个简单的HttpServer类。不幸的是,路由器JVM精简了这个类,所以我写了下面的类文件。
包ml . minli . tool . util;import javax . activation . mimetypesfiletypemap;导入Java . io . *;导入Java . net . *;公共类HttpServer扩展线程{private final int port;私有服务器套接字服务器套接字;private static final MimetypesFileTypeMap MimetypesFileTypeMap = new MimetypesFileTypeMap();public http server(int port){this . port = port;}@ Overridepublic void run(){try {server socket = new server socket(port);while(true){Socket Socket = server Socket . accept();http request handler http request handler = new http request handler(socket);http request handler . handle();socket . close();}} catch(Exception e){e . printstacktrace();}最后{if (serverSocket!= null amp amp!server socket . is closed()){try {server socket . close();} catch(Exception e){e . printstacktrace();}}}}私有静态类http request handler {私有最终套接字Socket;public http request handler(Socket Socket){this . Socket = Socket;}public void handle(){try {StringBuilder StringBuilder = new StringBuilder();InputStreamReader InputStreamReader = new InputStreamReader(socket . getinputstream());char[]chars = new char[1024];int标记;while((mark = inputstreamreader . read(chars))!=-1){stringbuilder . append(chars,0,mark);if(mark lt;chars . length){break;}}if(stringbuilder . length()= = 0){return;}//拦截每一行请求string[]lines = string builder . tostring()。拆分(" r n ");如果(!行[0]。isempty(){/intercept URLstring[]infos = lines[0]。拆分(" ");String info = URL decoder . decode(infos[1]," UTF-8 ");File文件;if(info . equals("/"){File = new File(USB info . USB path+"/index . html ");} else {File = new File(USB info . USB path+info);}/文件不存在。返回404if(!file . exists()){socket . get output stream()。write(("HTTP/1.1 404未找到 r n "+" Content-Type:text/html;charset=utf-8rn" +"rn ")。getBytes());返回;}String content type = mimetypesfiletypemap . get content type(file);socket.getOutputStream()。写((" HTTP/1.1 200 OK r n "+" Content-Type:"+Content Type+";charset=utf-8rn" +"rn ")。getBytes());FileInputStream文件输入流=新文件输入流(文件);byte[] bytes =新字节[1024];int length;while((length = file inputstream . read(bytes))!=-1){socket . get output stream()。write(字节,0,长度);}}} catch(Exception e){e . printstacktrace();}最后{if (socket!= null amp amp!socket . is closed()){try {socket . close();} catch(Exception e){e . printstacktrace();}}}}}}
由于我只打算先实现静态web服务器的分析,所以我打算这样实现:前端文件,如HTML、CSS、JS等。,都存储在u盘里,然后服务器解析文件返回,这样就简单多了。只需获取请求并解析它。但是,返回需要适当的内容类型,因此需要判断文件类型。所以用的是javax.activation包,原来是JDK1.8自带的,可惜路由器JVM精简了。但是,您可以通过Maven插件打包文件。
org . Apache . Felixmaven-bundle-plugin5 . 1 . 2true{ project . name }{ project . description }李玟ml . minli . tool . activatorOSGI-INF/USB info . XML*;scope = compile | runtimeinline=false
最后,在启动的实例类中调用它。这里,端口2222用于测试。值得注意的是,有些端口是路由器自己占用的,所以我们只能使用其他端口。
包ml . minli . tool;导入ml . minli . tool . util . http server;import org . OSGi . framework . bundle activator;导入org . OSGi . framework . bundle context;public class Activator实现bundle Activator {public Activator(){}@ Overridepublic void start(bundle context bundle context){new http server(22222)。start();}@ Overridepublic void stop(bundle context bundle context){}}
同时也要注意权限的问题。在很多地方,没有权限的程序会抛出异常。权限如下所示。
(org . OSGi . framework . package permission " * " import ")(Java . util . logging . logging permission " control ")(org . OSGi . framework . service permission " com . Huawei . hi link . rest . rest resource " " register ")(Java . io . file permission "/mnt/-" " read ")(com . Huawei . hi link . coreapi . perm . USB permission " * " list))(org . OSGi . framework
最终成功实现了路由器运行Web应用的功能,可以运行任何网页。同时,如果是一些常见的文件,通过URL访问相当于下载,那么做一个简单的NAS服务器似乎很容易。
结果暂时告一段落,因为当时还在准备考研,现在刚写完这些内容,现在可以再折腾一下,看看有什么可以申请的。如果有什么进展,我会继续分享。
这是我第一次在平台上分享技术内容。欢迎和我交流探讨。请喜欢并关注我!