项目中最近要搞个telnet远程登陆,需要浏览器进行实时交互。我们都知道,浏览器的http协议是无状态的,一次请求,三次握手,状态肯定是保证不了的,那到底该怎么办呢?
现在比较前卫的技术,例如websocket可以做到这一点,但是websocket是基于HTML5开发的,IE9以下版本不能支持,而且需要在tomcat7.0.47以上版本运行,而LZ项目组使用的是1.6版本,因此最终被LZ排除在外。那最笨的也是最有效的就是轮循(polling)了,就是定时刷新,采用ajax局部请求和刷新相关html页面。
贴个完成的页面给大伙瞅瞅,html样式,是个弹出框。。。
java连接telnet的代码还是比较简单的,commons-net-2.0.jar是工程依赖包,文字后贴上代码。当然,调试过程中,遇到了很多莫名其妙的问题。
1、首先遇到的困难是,输入命令后出现了---- More ----,噩梦啊,一页居然显示不完,LZ试着发送'\r\n'模拟回车,一行一行的读取,后来,LZ发现发送空格可以一次翻一页,原谅我linux小白。。。总算解决了问题。
2、接着就出现了一断乱码字符'x[42D'(x打不出来),百思不得其解,一个一个字符打印出来,居然是char=27,脱离操作,长见识了,出现more以后输入命令后换行,开头都会多这么一个鸟东西,而且是跟着52个无用字符,那么,过滤掉,ok。
3、然后就是时不时的假死,特别郁闷,打开JDK文档,里面是这么写的,InputStream。
public abstract int read()throws IOException 从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因为已经到达流末尾 而没有可用的字节,则返回值 -1。在输入数据可用、检测到流末尾或者抛出异常前,此方法一直阻塞。
从输入流中读取数据的下一个字节。返原来我们读取普通的文件的时候,都是一次性读取,流是以-1作为读取文件的结束,不会遇到阻塞的问题。而temlet是长连接,是Socket连接的一种,此时的流是一直可用的,所以很可能出现阻塞问题,所以读取的时候一定要自己增加结束判断,或者使用in.available()判断是否有可用资源,然后再使用in.read()方法。
4、我们都知道浏览器多次请求,肯定是多线程的,那么就需要有一个管理类去管理这些连接,管理类就不贴了,就是一个单例的map管理类,我是用户名+时间戳作为交互的key进行定位的,存储在map中,telnet工具类内部也有超时线程,10分钟后断开连接,防止占用过多的内存。
import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import org.apache.commons.net.telnet.TelnetClient; import org.apache.log4j.Logger; public class TelnetClientUtil { /** * log4j日志记录器 */ private static final Logger log = Logger.getLogger(TelnetClientUtil.class); /** * telnet客户端 */ private TelnetClient telnetClient = new TelnetClient(); /** * 输入流,接收返回信息 */ private InputStream in; /** * 向 服务器写入 命令 */ private PrintStream out; /** * 分割符 */ private char prompt = '$'; /** * 是否连接 */ public boolean isconnected = false; public void logout() { try { if(telnetClient.isConnected()) { telnetClient.disconnect(); } isconnected = false; } catch (IOException e) { log.info(e); } } public TelnetClientUtil(String ip, int port, String user, String password) { try { telnetClient.setConnectTimeout(30000); //telnetClient.setSoTimeout(30000); telnetClient.connect(ip, port); in = telnetClient.getInputStream(); out = new PrintStream(telnetClient.getOutputStream()); //this.prompt = user.equals("root") ? '#' : '$'; if(getResponse(":").contains("Username:")) { write(user); } if(getResponse(":").contains("Password:")) { write(password); } if(getResponse(">").contains(">")) { log.info("[telnet] connect success!"); //启动线程监控,断开无用连接 isconnected = true; new Thread(new TimeoutThread()).start(); } else { log.info("[telnet] connect error: connect to [" + ip + ":" + port + "] fail!"); logout(); } } catch (Exception e) { log.info("[telnet] connect error: connect to [" + ip + ":" + port + "] fail!"); logout(); } } /** * 发送命令无返回值 * @param command * @return */ private void write(String command) { try { out.println(command); out.flush(); } catch (Exception e) { log.info(e); } } /** * 发送指令 * @param command * @param ip * @param key * @return */ public String sendCommand(String command, String ip, String key) { try { write(command); String response = getResponse(">"); log.info("[telnet] response: [" + response + "], ip=[" + ip + "], key=[" + key + "]"); return "<br/>" + response.replaceAll("<", "<") .replaceAll(">", ">") .replaceAll(" ", " ") .replaceAll("\n", "<br/>"); } catch (Exception e) { log.info(e); } return null; } /** * 获取返回结果 * @param pattern * @return */ private String getResponse(String pattern) { try { char lastChar = pattern.charAt(pattern.length() - 1); StringBuffer sb = new StringBuffer(); String content = ""; char ch; while(sb.length() < 4000) { ch = (char) in.read(); sb.append(ch); if (ch == lastChar && sb.toString().endsWith(pattern)) { break; } dealWithMore(sb); } content = sb.toString(); //读完的所有的流数据 log.info("in.available size is" + in.available()); while(in.available() != 0) { ch = (char) in.read(); sb.append(ch); dealWithMore(sb); } return content; } catch (Throwable e) { log.info(e); } return null; } /** * 处理出现more更多的场景 * @param sb * @throws Exception */ private void dealWithMore(StringBuffer sb) throws Exception { if(sb.toString().endsWith("---- More ----")) { log.info("enter [space] to continue."); int index = sb.indexOf(" ---- More ----"); sb.delete(index, index + 16); write(" "); Thread.sleep(100); //more命令后输入回车,会有一个脱离操作,char=27,默认过滤掉52个无用字符 for(int i = 0; i < 52; i++) { in.read(); } log.info("skip [pause] to continue."); } } class TimeoutThread implements Runnable { @Override public void run() { long startTime = System.currentTimeMillis(); while(true) { //超过10分钟断开连接 if(System.currentTimeMillis() - startTime > 10 * 60 * 1000) { log.info("telnet超时,断开连接!"); logout(); break; } try { //每一分钟检测一次 Thread.sleep(1000 * 60); } catch (InterruptedException e) { e.printStackTrace(); } } } } }最后不得不提一点,安全性的问题,当然这个需要用户那边去保证,万一用户发送了什么不该发送的命令,呵呵,所有操作都要log日志的,这个你们都懂的,好了,希望此文对大家有所帮助。
相关推荐
使用SignalR在浏览器中进行Telnet Towser是允许从浏览器访问telnet服务的应用程序。 telnet客户端在IIS Web服务器上运行,而终端模拟器在浏览器中运行。 这两个组件使用SignalR进行通信。 设置 通过编辑web.config...
1、支持windows远程桌面,ssh登陆,telnet登陆 2、支持服务器(设备)信息加密保存, 3、支持Excel批量导入 4、支持服务器信息导出至RDP文件 5、内置浏览器,支持访问各类web界面的登陆方式 6、支持服务器信息网络...
1、支持windows远程桌面,ssh登陆,telnet登陆 2、支持服务器(设备)信息加密保存, 3、支持Excel批量导入 4、支持服务器信息导出至RDP文件 5、内置浏览器,支持访问各类web界面的登陆方式 6、支持服务器信息网络...
1、支持windows远程桌面,ssh登陆,telnet登陆 2、支持服务器(设备)信息加密保存, 3、支持Excel批量导入 4、支持服务器信息导出至RDP文件 5、内置浏览器,支持访问各类web界面的登陆方式 6、支持服务器信息...
1、支持windows远程桌面,ssh登陆,telnet登陆 2、支持服务器(设备)信息加密保存, 3、支持Excel批量导入 4、支持服务器信息导出至RDP文件 5、内置浏览器,支持访问各类web界面的登陆方式 6、支持服务器信 ...
SecureCRT是一款用于连接运行包括Windows、UNIX和VMS的远程系统的理想工具。通过使用内含的VCP命令行程序可以进行加密文件的传输。有流行CRT Telnet客户机的所有特点,包括:自动注册、对不同主机保持不同的特性、打印...
SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,同时支持Telnet和rlogin协议。SecureCRT是一款用于连接运行包括Windows、UNIX和VMS的远程系统的理想工具。通过使用内含的VCP命令行程序可以进行加密文件的传输...
SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,同时支持Telnet和rlogin协议。SecureCRT是一款用于连接运行包括Windows、UNIX和VMS的远程系统的理想工具。通过使用内含的VCP命令行程序可以进行加密文件的传输...
1、支持windows远程桌面,ssh登陆,telnet登陆 2、支持服务器(设备)信息加密保存, 3、支持Excel批量导入 4、支持服务器信息导出至RDP文件 5、内置浏览器,支持访问各类web界面的登陆方式 6、支持服务器资料网络...
Rconsole远程管理工具,支持VNC/RDP/SPICE/SSH/TELNET协议。支持连接到Libvirt管理的虚拟机。使用websocket协议传输数据,在HTML5浏览器中使用canvas显示。使用Golang开发,性能卓越,部署简单。TODO连接到XenServer...
Telnet链接让你方便地进行远程Telnet操作。 Administrator:进行管理员操作,对计算机的各项资源和服务进行管理,包括最高权限的服务管理和用户管理。 Performance:服务器性能统计,随时监测服务器的CPU、...
(压缩包内含注册信息)SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,同时支持Telnet和rlogin协议。SecureCRT是一款用于连接运行包括Windows、UNIX和VMS的远程系统的理想工具。通过使用内含的VCP命令行程序...
FTP 支持用户验证 提供异种计算机之间有限的数据转换 通用命令结构 端口号:TCP 20,21 匿名FTP(Web浏览器):服务器所有目录设为"只读" CuteFTP,CrossFTP,大众FTP 远程网络访问安全技术全文共27页,当前为第11...
SecureCRT是一款用于连接运行包括Windows、UNIX和VMS的远程系统的理想工具。通过使用内含的VCP命令行程序可以进行加密文件的传输。有流行CRTTelnet客户机的所有特点,包括:自动注册、对不同主机保持不同的特性、打印...
只要在服务器端安装该软件,只需使用一个支持 Java的浏览器便可通过键盘或鼠标、以及预先设置的帐号口令就可以远程控制该服务器,还可以通过Telnet/SSH 端口控制,具有IP过滤、IP黑名单、128-bit SSL 加密等安全...
打开远程telnet服务代码 浏览器 屏幕精灵 探测Windows主机的NetBIOS信息 获取asp代码的程序 聊天系统的列子 邮件发送代码 远程控制程序 sqlworm蠕虫 tini2后门代码 ">精典的VC++黑客...
s-term是一个能在windows 9x/nt/2000平台下运行的telnet远程登陆软件,设置简单,使用方便。s-term的一大特色是:采用了多文档界面,能在一个框架中打开多个窗口,最小化时能缩小为图标,隐藏在任务栏中,这个功能是...
SecureCRT是一款支持SSH(SSH1和SSH2)的终端仿真程序,同时支持Telnet和rlogin协议。SecureCRT是一款用于连接运行包括Windows、UNIX和VMS的远程系统的理想工具。通过使用内含的VCP命令行程序可以进行加密文件的传输...
SecureCRT是一款用于连接运行包括Windows、UNIX和VMS的远程系统的理想工具。通过使用内含的VCP命令行程序可以进行加密文件的传输。有流行CRTTelnet客户机的所有特点,包括:自动注册、对不同主机保持不同的特性、...