Web_telnet 通过JAVA实现网页上面的命令行远程工具 以及对于流的理解
前言
这几天研究了一下如何在web页面上通过telnet 连接一个远程的机器,通过命令行进行控制,让然,B/S架构的项目,如果直接通过
浏览器是无法和远程机器进行通信的,我们就得借助后端来帮助实现这样的一个功能需求,具体的实现逻辑是:
用户————>控制浏览器命令行界面————>发送命令到后端服务器————>后端服务器连接socket————>推送用户的命令
telnet Server ————>后端服务器输入流接受返回字符——————>websocket 推送到前端完成交互
telnet
可能很多人都知道ssh,估计很少会了解到关于telnet的东西,但是又结合起来说,其实两个都是一种协议,可以远程操控,
但是telnet 在传输过程中存在着不安全的因素,因为传输都未经过加密,而都是明文,这就在远程连接中,很容易就会被抓包,出现问题,
但SSH 就好比是加强版的telnet ,在传输过程中的数据进行加密,进而减少了被盗取的风险。并且所有的SSH都是经过压缩的,在网络上的
传输速率也很优秀,这样多方面优秀的情况下,自然而然的就会代替掉telnet
并不是这样说telnet 就没什么用了,也不是这样子的,我们通过搭建这样一个demo 学习的是这样的搭建过程中去了解建立连接的过程以及交互的过程
同样的,就算改编成SSH 其实也是这样的一个过程,学习就是一个不断探索的过程
开始
后端的话,从Springboot 入手,快速的搭建一个web工程,我们主要用这个web工程来接受前端发送过来的命令请求。
包括:连接、断开、发送命令等等。
最主要的,就是采用commons-net包下面的TelnetClient
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.6</version>
</dependency>
就好比我们的交换机作为一个Telnet的服务端,而我们的本机就作为一个Telnet的客户端,客户端发起请求,服务端相应,与B/S其实一样的
这里我就摘一些关键的部分来进行讲解,其他的请clone 项目进行查看
创建一个telnet 客户端
其实创建一个telnet 客户端是很简单的,就只需要new一个对象,而后填写ip地址和端口,端口默认是23,可以不写,就打开了一个telnet的Connection
telnetClient = new TelnetClient();
telnetClient.connect(ip,port); inputStream = telnetClient.getInputStream();
outputStream = telnetClient.getOutputStream();
从客户端得到两个流,一个输入流,一个输出流,这里就会涉及到JAVA关于IO相关的知识,当然网络上一般通行都是采用字节流
inputStream 输入流 outputStread 输出流
对于输入流和输出流相对于模糊的小伙伴,这里给大家加深一下理解,从字面意思上理解
输入流:就是输进来的
输出流:就是丢出去的
其实这样理解的话,丢失了一个基于的对象。那就是,到底是基于客户端还是服务端呢,我这里简单的画个图
就好比你的程序要读取一个文件,这个时候就需要用到输入流,输入流提供一个read的方法
我得把日志信息写入到日志文件里,这个时候就需要用到输出流,输出流提供一个write() 方法
输出流有一个flush() 强制刷新的方法 强制清空和写入
一个好的习惯,流用完之后要进行关闭!!!!!
在当前的环境里面,输入流就好比是客户端给我们返回的数据,而输出流才是我们推送命令的
输入命令
切记在命令后加入一个换行符,这就好比我们在telnet 客户端上面操作的时候,写完一句就需要敲一个回车,一样的道理。
通过输出流的write 方法写入到输出流里面,flush将输出流清空和强制写入命令。
public String sendCommand(String send) throws IOException { //加入换行符
send = send + "\n"; if (null == telnetClient) {
return "连接已关闭";
}
outputStream.write(send.getBytes());
outputStream.flush(); return "发送成功";
}
读取服务端的返回
上面已经反复叙述过了,服务端的返回我们需要采用输入流进行接收,同样的,需要从流里面读取出我们需要的字节,并将其转换为字符
通过webSocket 推送到前台进行展示
这时候就需要起一个线程来操作了,因为你不知道什么时候回接收到推送的消息,所以这个线程还不能停掉,得设置为后台线程,让它在开启连接后一直
在后台保持活动状态,这里就需要了解一下:守护线程
守护线程 、后台线程
通过给一个线程设置setDaemon(true) 的形式标记这个线程为守护线程,也就是后台线程,线程启动前必须启动这个线程
对于停止这个线程的方法嘛 那就是执行中断,在这个线程的逻辑代码中判断是否中断,中断则跳出这个线程,线程执行完毕
这个线程也就停掉了呗!
通过new 一个线程类,主要看一下这个类的实现方法
outputThread = new InputPrintThread(inputStream); //守护线程
outputThread.setDaemon(true);
outputThread.start();
通过一个while 循环的方式时刻执行是否中断的方法和 对输入流进行读取,因为读取在读取不到字节的时候会发生阻塞,所以这样是很有必要的
因为在读取不到的时候,会阻塞这个线程,若读取流在文件末尾,则会返回-1 我们只需要判断不是-1继续读取就好了
注意:这里说的是:读取出一些字节,并不是所有的字节,一次返回过来的字节它可能会读取多次,所以不能只循环一次就判断这个就完了
@Override
public void run() { int num = 0;
//字节缓冲
char[] bytes = new char[1024];
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
try {
//这里会发生阻塞,通过websocket推送进行
while (!interrupted() && (num = inputStreamReader.read(bytes)) != -1) { for (int i = 0; i < num; i++) {
char ab = bytes[i];
WebSocketServer.sendInfo(ab + "", SocketIdEnum.TELNET.getValue());
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
webSocket 推送
这一部分对于Springboot 来说整合WebSocket 简直是太简单了,一个POM依赖以及简单的几行配置即可开启
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
这里我就不细说了:我的内容也是参考这一篇文章:请参阅
https://blog.csdn.net/moshowgame/article/details/80275084
telnet 客户端的配置
在windows 里面开启telnet 基本步骤:搜索windows功能
找到并开始这一项即可,即可在命令行里面通过telnet + ip 进行远程访问,
telnet 测试服务端
很多小伙伴在昨晚后,不知如何去测试telnet的连通性以及代码的测试,缺少一个测试的环境
手头又没有其他闲置的电脑或者是交换机,可以参考手头建立一个虚拟机的方式,这样也行,或者就
采用华为的ENSP 创建一个虚拟的交换机后,通过自己电脑的虚拟网卡接入到虚拟交换机,这样其实也是可以通过telnet
进行访问的,ENSP的安装这里略过,这里给一个链接:https://share.weiyun.com/5kmSEYr
而后新建一个交换机通过虚拟网卡的映射进行连接后,通过本机PING 这台交换机的IP 若ping通则证明连接正常
若不清楚配置交换机的telnet 可以参阅:https://www.cnblogs.com/pipci/p/8075686.html
划分vlan 这些基础我就不细说了,自行参考
测试效果
对与一个写后台的人来说:前台这样子其实已经很不错了
哈哈 只能简单的写个窗口,然后将后台推送的内容push到页面上
因为是一个小的测试demo 有兴趣的可以进行改造升级更好的CSS美化
小结
关于研究这个web版本的telnet 其实还是涉及到很多东西,比如又再一次的学习到了流的概念以及
之前从未知道这个输入流还会存在阻塞的问题 以及如何优雅的关闭流以及flush 强制刷新写入等诸多的问题
虽然SSH已经是远程当中的主流,telnet 也未必没得用,总结一下总是好的。
参考
交换机telnet配置 https://www.cnblogs.com/pipci/p/8075686.html
springboot 配置websocket https://www.cnblogs.com/pipci/p/8075686.html
代码开源
https://gitee.com/mrc1999/web-telnet
Web_telnet 通过JAVA实现网页上面的命令行远程工具 以及对于流的理解的更多相关文章
- Flash文件在asp页面无法播放,网页上面的Flash文件在火狐浏览器不播放
第一个问题:Flash文件放到asp页面以后无法播放. 解决方法:用浏览器打开页面->F12,选择Network,如下图: 然后刷新页面,如下图: 点击左侧状态是404的文件,如图: 可以发现F ...
- UiPath工具取得网页上面的数据,写入到csv,Outlook邮件发送
问题描述: 想取得网页上面的股票价格,之后写入到csv文本里面之后添加附件发送邮件. 解决方法: 利用UIPath工具来取得数据,之后写入再发送. 具体步骤: 1.打开网页,之后找到所显示的股票行情的 ...
- phpmyadmin和网页上面的乱码问题
前段时间做了个留言板,但是总是出现乱码,而且出现了无法插入的情况:发现这么个问题:在phpmyadmin里面默认的编码是瑞士的一个编码:我就郁闷了为什么这么一个通用软件的编码放着UTF-8或者是GBK ...
- Ubuntu server版上使用命令行操作VPNclient
Ubuntu server版上使用命令行操作VPNclient VPN,虚拟专用网络,这个技术还是非常有用的.近期笔者參与的项目中就使用上了VPN,大概情况是这种.有两个开发团队,在异地,代码服务器在 ...
- mac上使用命令行显示隐藏文件
终端中输入命令 打开<终端> - 粘贴下面的两行命令执行 defaults write com.apple.finder AppleShowAllFiles TRUEkillall Fin ...
- [编译] 7、在Linux下搭建安卓APP的开发烧写环境(makefile版-gradle版)—— 在Linux上用命令行+VIM开发安卓APP
April 18, 2020 6:54 AM - BEAUTIFULZZZZ 目录 0 前言 1 gradle 安装配置 1.1 卸载系统默认装的gradle 1.2 下载对应版本的二进制文件 1.3 ...
- 如何让 Windows 上的命令行工具更好用
侯爵老师视频详解:如何让 Windows 上的命令行工具更好用 很多 Windows 用户在打开这个小黑窗时,都会情不自禁的感慨,「实在是太丑了--」 实际上如果你用的是 Windows 8 或 Wi ...
- [转帖]如何在Linux上使用命令行查看硬件信息
如何在Linux上使用命令行查看硬件信息 时间:2016-01-13 作者:admin 分类:新手入门 阅读:126次 http://embeddedlinux.org.cn/emb-linux/ ...
- 【转】curl 命令行下载工具使用方法小结
获取curl curl 命令行下载工具 curl的官方网站为: http://curl.haxx.se官方下载页面为:http://curl.haxx.se/download.html 你可能并不清楚 ...
随机推荐
- 获得审批人的id
//sima 传入uid 得到所有上级部门负责人id private function partment($uid,$level='') { //传入部门id 返回本部门所有上级部门负责人的id $d ...
- 详解如何在Laravel中增加自定义全局函数
http://www.php.cn/php-weizijiaocheng-383928.html 如何在Laravel中增加自定义全局函数?在我们的应用里经常会有一些全局都可能会用的函数,我们应该怎么 ...
- Android 错误:IllegalStateException: Can not perform this action after onSaveInstanceState
今天做Fragment切换.状态保存功能的时候,出现了这个错误: E/AndroidRuntime(12747): Caused by: java.lang.IllegalStateException ...
- 唯一索引与非唯一索引区别(UNIQUE INDEX, NON-UNIQUE INDEX)
索引是我们经常使用的一种数据库搜索优化手段.适当的业务操作场景使用适当的索引方案可以显著的提升系统整体性能和用户体验.在Oracle中,索引有包括很多类型.不同类型的索引适应不同的系统环境和访问场景. ...
- C++ 第四次作业 继承
继承 继承时从新的类从已有类那里得到新的特征.继承实现了代码的重用,极大地减少了代码量,同时通过新增成员,加入了自身的独有特性,达到了程序的扩充. 派生类继承了基类的全部数据类和除了构造函数.析构函数 ...
- Rikka with Mista 线段树求交点个数
由于上下线段是不可能有交点的 可以先看左右线段树,按照y递增的顺序,对点进行排序. 升序构造,那么对于从某一点往下的射线,对于L,R进行区间覆盖,线段交点个数就是单点的被覆盖的次数. 降序构造,那么对 ...
- H3C 电路交换连接模型
- Ant design在vue,react的引入
文章地址: https://www.cnblogs.com/sandraryan/ 最近由于 一些不可描述的原因 要研究一下Ant design这个前端框架. 祭上官网: https://ant.de ...
- [转]Android Studio实现代码混淆
1,在build.grandle添加,其中规则写在proguard-rules.pro中,也可以自定义一个文件,将其代替,比如eclipse常用的 proguard-project.txt: bui ...
- 【CSS3 + 原生JS】移动的标签
左图为本博客右侧截取的GIF图,右图为代码效果 HTML: <!DOCTYPE html> <html lang="en"> <head> &l ...