关于telnet协议的研究以及用java进行封装实现自己的telnet客户端(转)
最近在做一个远程控制的模块,其中用到了telnet协议,开始用的是apache-net包的telnetclient,但发现问题不少,比较慢,还有就是判断是否read完毕的问题。后来经过讨论打算实现自己的telnet,于是网址打罗了一番,找了一个,但是bug也不少,就开始封装。具体的telnet我已经发过2篇文章了,这里再发布一个深化封装的telnet实现。
仅供参考,可以在windows和linux上运行。
- package baby.net.base;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- import java.net.InetSocketAddress;
- import java.net.Socket;
- import java.util.ArrayList;
- import org.apache.log4j.Logger;
- /**
- * telnet 基本连接类
- *
- * @description
- * @author weichaofan
- * @date 2013年10月25日
- */
- public class TelnetBase {
- private static final byte SB = (byte) 250;// 子选项开始
- private static final byte SE = (byte) 240;// 子选项结束
- private static final byte WILL = (byte) 251;// 选项协商
- private static final byte WONT = (byte) 252;// 选项协商
- private static final byte DO = (byte) 253;// 选项协商
- private static final byte DONT = (byte) 254;// 选项协商
- private static final byte IAC = (byte) 255;// 数据字节255
- private static final byte ECHO = (byte) 1;// 回显
- private static final byte IS = (byte) 0;// 是
- private static final byte SUPPRESS = (byte) 3;// 抑制继续进行
- private static final byte TT = (byte) 24;// 终端类型
- private InputStream is;
- private OutputStream os;
- private Socket client;
- private byte[] readBuffer = new byte[20 * 1024];
- private int miniReadIntervalMillSec = 3000;// 最短read阻塞间隔时间-毫秒
- private int connectTimeout = 1000;// 连接超时时间
- private int maxReadTimeout = 5000;
- public static String[] failTags = { "Failed", "fail", "incorrect" };
- public static String[] loginTags = { "$", "#", ">", "ogin", "@" };
- public static String[] commondEndTags= { "$", "#", ">"};
- public static String[] allTags = { "Failed", "fail", "incorrect", "$", "#",
- ">", "ogin", "@" };
- private String ip;
- private int port = 23;
- Logger logger = Logger.getLogger(getClass());
- /**
- *
- * 打开telnet连接
- *
- * @param ip
- * @param port
- * 23
- *
- * @return
- *
- * @throws CmdException
- */
- public TelnetBase(String ip) {
- this(ip, 23);
- }
- /**
- *
- * 打开telnet连接
- *
- * @param ip
- * @param port
- * @return
- * @throws CmdException
- */
- public TelnetBase(String ip, int port) {
- this.ip = ip;
- this.port = port;
- }
- /**
- * 连接
- *
- * @return
- * @throws Exception
- */
- public String connect() throws Exception {
- try {
- client = new Socket();
- client.connect(new InetSocketAddress(ip, port), connectTimeout);
- client.setSoTimeout(miniReadIntervalMillSec);// 设置is的read方法阻塞时间
- is = client.getInputStream();
- os = client.getOutputStream();
- } catch (Exception e) {
- this.close();
- throw new Exception(e);
- }
- return readKeyWords("ogin:");
- }
- /**
- *
- * 读取回显,并进行telnet协商
- *
- * @return
- *
- * @throws IOException
- */
- public String recieveEcho() throws IOException {
- int len = is.read(this.readBuffer);
- ArrayList<Byte> bsList = new ArrayList<Byte>();
- ArrayList<Byte> cmdList = new ArrayList<Byte>();
- for (int i = 0; i < len; i++) {
- int b = this.readBuffer[i] & 0xff;// &0xff是为了防止byte的255溢出,java中byte的取值是-128~127
- if (b != 255) {
- if (b == '\n' || b == '\0') {// NVT中行结束符以'\r\n'表示,回车以'\r\0表示'
- continue;
- }
- bsList.add((byte) b);
- continue;
- }
- cmdList.add(IAC);
- switch (this.readBuffer[++i] & 0xff) {
- case 251:// 服务器想激活某选项
- if ((readBuffer[++i] & 0xff) == 1) {// 同意回显
- cmdList.add(DO);
- cmdList.add(ECHO);
- } else if ((readBuffer[i] & 0xff) == 3) {// 同意抑制继续执行
- cmdList.add(DO);
- cmdList.add(SUPPRESS);
- // cmdList.add(GA);
- } else {// 不同意其他类型协商
- cmdList.add(DONT);
- cmdList.add(readBuffer[i]);
- }
- break;
- case 253:// 服务器想让客户端发起激活某选项
- if ((readBuffer[++i] & 0xff) == 24) {// 终端类型
- cmdList.add(WONT);// 同意激活终端类型协商
- cmdList.add(TT);
- } else if ((readBuffer[i] & 0xff) == 1) {
- cmdList.add(WILL);
- cmdList.add(ECHO);
- } else {
- cmdList.add(WONT);// 不同意其他类型协商
- cmdList.add(readBuffer[i]);
- }
- break;
- case 250:// 子选项开始
- cmdList.add(SB);
- if ((readBuffer[++i] & 0xff) == 24
- && (readBuffer[++i] & 0xff) == 1) {// 发送你的终端类型
- cmdList.add(TT);
- cmdList.add(IS);// 我的终端类型是
- cmdList.add((byte) 'V');
- cmdList.add((byte) 'T');
- cmdList.add((byte) '1');
- cmdList.add((byte) '0');
- cmdList.add((byte) '0');
- }
- break;
- case 240:// 子选项结束
- cmdList.add(SE);
- break;
- case 252:// 必须同意
- cmdList.add(DONT);
- cmdList.add(readBuffer[++i]);
- break;
- case 254:// 必须同意
- cmdList.add(WONT);
- cmdList.add(readBuffer[++i]);
- break;
- }
- }
- // 如果有协商则向服务端发送协商选项
- if (cmdList.size() > 0) {
- byte[] writeBuffer = new byte[cmdList.size()];
- for (int i = 0; i < cmdList.size(); i++) {
- writeBuffer[i] = cmdList.get(i);
- }
- os.write(writeBuffer);
- }
- // 组织回显字符
- int size = bsList.size();
- String str = "";
- if (size > 0) {
- byte[] bs = new byte[size];
- for (int i = 0; i < size; i++) {
- bs[i] = bsList.get(i).byteValue();
- }
- str = new String(bs, "gbk");
- } else {
- // 如果是协商,则回传协商信息
- if (cmdList.size() > 0) {
- str = recieveEcho();
- }
- }
- // log(len, cmdList);
- return str;
- }
- private void log(int len, ArrayList<Byte> cmdList) {
- logger.debug("read===== ");
- for (int i = 0; i < len; i++) {
- logger.debug(readBuffer[i] & 0xff);
- logger.debug(" ");
- }
- if (cmdList.size() > 0) {
- logger.debug("write==== ");
- for (int i = 0; i < cmdList.size(); i++) {
- logger.debug(cmdList.get(i) & 0xff);
- logger.debug(" ");
- }
- }
- }
- /**
- * 用户名 命令中不要包括回车、换行
- *
- * @param cmd
- * @param keyWords
- * @return
- */
- public String sendUserName(String name) throws Exception {
- name += "\r\n";
- os.write(name.getBytes());
- return readKeyWords("assword");
- }
- /**
- * 密码 命令中不要包括回车、换行
- *
- * @param cmd
- * @param keyWords
- * @return
- */
- public String sendUserPwd(String pwd) throws Exception {
- pwd += "\r\n";
- os.write(pwd.getBytes());
- return readKeyWords(allTags);
- }
- /**
- * 命令中不要包括回车、换行
- *
- * @param cmd
- * @param keyWords
- * @return
- */
- public String sendCmd(String cmd, String... keyWords) throws Exception {
- return sendCmd(cmd,false,keyWords);
- }
- /**
- * 命令中不要包括回车、换行
- *
- * @param cmd
- * @param keyWords
- * @return
- */
- public String sendCmd(String cmd,boolean excludeCommandCheck, String... keyWords) throws Exception {
- os.write((cmd + "\r\n").getBytes());
- if(!excludeCommandCheck){
- return readKeyWords(cmd,maxReadTimeout,keyWords);
- }else{
- return readKeyWords(keyWords);
- }
- }
- /**
- * 命令中不要包括回车、换行 默认搜索条件为$、#、>
- * 不包含执行命令中的关键字
- * @param cmd
- * @param keyWords
- * @return
- */
- public String sendCommand(String cmd) throws Exception {
- return sendCommand(cmd,false);
- }
- /**
- * 命令中不要包括回车、换行 默认搜索条件为$、#、>
- * 是否包含执行命令中的关键字
- * @param cmd
- * @param keyWords
- * @return
- */
- public String sendCommand(String cmd,boolean excludeCommandCheck) throws Exception {
- os.write((cmd + "\r\n").getBytes());
- if(!excludeCommandCheck){
- return readKeyWords(cmd,maxReadTimeout,commondEndTags);
- }else{
- return readKeyWords(commondEndTags);
- }
- }
- /**
- * 命令中不要包括回车、换行 默认搜索条件为$、#、>
- * 不包含执行命令中的关键字
- * @param cmd
- * @param timeOut
- * @param keyWords
- * @return
- */
- public String sendCommand(String cmd, long timeOut) throws Exception {
- return sendCommand(cmd,timeOut, false);
- }
- /**
- * 命令中不要包括回车、换行 默认搜索条件为$、#、>
- * 是否包含执行命令中的关键字
- * @param cmd
- * @param timeOut
- * @param keyWords
- * @return
- */
- public String sendCommand(String cmd, long timeOut,boolean excludeCommandCheck) throws Exception {
- os.write((cmd + "\r\n").getBytes());
- if(!excludeCommandCheck){
- return readKeyWords(cmd,timeOut, commondEndTags);
- }else{
- return readKeyWords(timeOut, commondEndTags);
- }
- }
- /**
- * 命令中不要包括回车、换行
- *
- * @param cmd
- * @param timeOut
- * @param keyWords
- * @return
- */
- public String sendCmd(String cmd, long timeOut, String... keyWords)
- throws Exception {
- return sendCmd(cmd,false,timeOut, keyWords);
- }
- /**
- * 命令中不要包括回车、换行
- *
- * @param cmd
- * @param timeOut
- * @param keyWords
- * @return
- */
- public String sendCmd(String cmd, boolean excludeCommandCheck,long timeOut, String... keyWords)
- throws Exception {
- os.write((cmd + "\r\n").getBytes());
- if(!excludeCommandCheck){
- return readKeyWords(cmd,timeOut, keyWords);
- }else{
- return readKeyWords(timeOut, keyWords);
- }
- }
- /**
- *
- * 关闭telnet连接
- */
- public void close() {
- if (is != null) {
- try {
- is.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- if (os != null) {
- try {
- os.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- if (client != null) {
- try {
- client.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- /**
- *
- * 读取期望值,使用默认超时时间5秒
- *
- * @param keyWords
- *
- * @return
- */
- public String readKeyWords(String... keyWords) {
- return this.readKeyWords(maxReadTimeout, keyWords);
- }
- /**
- *
- * 读取期望值
- *
- * @param timeOut
- * 超时时间
- *
- * @param keyWords
- *
- * @return
- *
- * @throws CmdException
- */
- public String readKeyWords(long timeOut, String... keyWords) {
- String rv = "";
- long nextTime = 0;
- long endTime = System.currentTimeMillis() + timeOut;
- do {
- try {
- String _rv = this.recieveEcho();
- rv += _rv;
- } catch (IOException e) {
- nextTime = endTime - System.currentTimeMillis();
- }
- } while (!this.findKeyWord(keyWords, rv) && nextTime >= 0);
- if (nextTime < 0)
- System.err.println("Read TimeOut...Echo:\n" + rv);
- return rv;
- }
- /**
- *
- * 读取期望值 排除command中含有的关键字
- *
- * @param timeOut
- * 超时时间
- *
- * @param keyWords
- *
- * @return
- *
- * @throws CmdException
- */
- public String readKeyWords(String command,long timeOut, String... keyWords) {
- String rv = "";
- long nextTime = 0;
- long endTime = System.currentTimeMillis() + timeOut;
- do {
- try {
- String _rv = this.recieveEcho();
- rv += _rv;
- } catch (IOException e) {
- nextTime = endTime - System.currentTimeMillis();
- }
- } while (!this.findKeyWord(command,keyWords, rv) && nextTime >= 0);
- if (nextTime < 0)
- System.err.println("Read TimeOut...Echo:\n" + rv);
- return rv;
- }
- /**
- *
- * 查找关键字
- *
- * @param keyWords
- *
- * @param str
- *
- * @return
- */
- public boolean findKeyWord(String[] keyWords, String str) {
- if (str == null || "".equals(str))
- return false;
- if (keyWords == null || keyWords.length == 0)
- return true;
- for (int i = 0; i < keyWords.length; i++) {
- if (str.indexOf(keyWords[i]) != -1)
- return true;
- }
- return false;
- }
- /**
- *
- * 查找关键字 排除command中含有的关键字
- *
- * @param keyWords
- *
- * @param str
- *
- * @return
- */
- public boolean findKeyWord(String command,String[] keyWords, String str) {
- if (str == null || "".equals(str))
- return false;
- if (keyWords == null || keyWords.length == 0)
- return true;
- System.out.println(str);
- if(-1 != str.indexOf(command)){
- str=str.substring(str.indexOf(command)+command.length());
- for (int i = 0; i < keyWords.length; i++) {
- if (str.indexOf(keyWords[i]) != -1)
- return true;
- }
- }
- return false;
- }
- /**
- * 最短读阻塞时间
- *
- * @return
- */
- public int getMiniReadIntervalMillSec() {
- return miniReadIntervalMillSec;
- }
- public void setMiniReadIntervalMillSec(int miniReadIntervalMillSec) {
- this.miniReadIntervalMillSec = miniReadIntervalMillSec;
- }
- /**
- * 连接超时时间
- *
- * @return
- */
- public int getConnectTimeout() {
- return connectTimeout;
- }
- public void setConnectTimeout(int connectTimeout) {
- this.connectTimeout = connectTimeout;
- }
- /**
- * 最大读阻塞时间
- *
- * @return
- */
- public int getMaxReadTimeout() {
- return maxReadTimeout;
- }
- public void setMaxReadTimeout(int maxReadTimeout) {
- this.maxReadTimeout = maxReadTimeout;
- }
- }
http://blog.csdn.net/chaofanwei/article/details/14130179
http://www.iteye.com/topic/284636
关于telnet协议的研究以及用java进行封装实现自己的telnet客户端(转)的更多相关文章
- Telnet 协议详解
Telnet 协议详解 一.概述 ============================================================ Telnet 协议是 TCP/IP 协议族中 ...
- telnet协议的作用详解,以及telnet端口号介绍
转:http://www.ctowhy.com/382.html Telnet协议,工作在TCP/IP协议栈的“应用层”,telnet是一种使用命令行的远程终端管理的协议,可以远程连接到网络设备上,并 ...
- Telnet协议详解
转:http://www.cnblogs.com/dazhaxie/archive/2012/06/27/2566054.html 1. 概述 Telnet协议是TCP/IP协议族中的一员,是Inte ...
- Telnet协议详解(远程登陆协议)
1. 概述 Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议.Telnet协议的目的是提供一个相对通用的,双向的,面向八位字节的通信方法,允许界面终端设备和面向终 ...
- 【Telnet】使用Telnet协议连接到远程Shell执行脚本
介绍 本文介绍如何通过Telnet协议连接到远程Shell,执行脚本,并获取执行结果: 相关文章: <[Jsch]使用SSH协议连接到远程Shell执行脚本>http://www.cnbl ...
- Atitit onvif协议获取rtsp地址播放java语言 attilx总结
Atitit onvif协议获取rtsp地址播放java语言 attilx总结 1.1. 获取rtsp地址的算法与流程1 1.2. Onvif摄像头的发现,ws的发现机制,使用xcf类库1 2. 调用 ...
- java 通过TCP\UDP 协议实现多人聊天,点对点,文件传送-----分服务器端和客户端
java 通过TCP\UDP 协议实现多人聊天,点对点,文件传送-----分服务器端和客户端 启动界面如下图: 首先启动服务器: 客户端登陆,登陆成功后为: 默认发送是全部用户,是多人发送. 当在边列 ...
- telnet协议:简介与安装使用
Telnet简介 Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式.它为用户提供了在本地计算机上完成远程主机工作的能力.在终端使用者的电脑上使用teln ...
- 如何在Windows系统上利用Telnet协议连接Linux服务器
Telnet协议是Internet远程登录服务的标准协议,它为用户提供了在本地计算机上完成远程主机工作的能力.很多终端使用者都习惯在计算机上利用Telnet会话来远程控制服务器.这里小编就分两步为大家 ...
随机推荐
- OCP读书笔记(14) - 管理数据库性能
搜集统计信息 1. dbms_stats gather_schema_stats 1)option:有四个选项: a.gather empty:只分析目前还没有搜集过统计信息的表 SQL> co ...
- Linux Shell脚本编程--curl命令详解
用途说明 curl命令是一个功能强大的网络工具,它能够通过http.ftp等方式下载文件,也能够上传文件.其实curl远不止前面所说的那些功能,大家可以通过man curl阅读手册页获取更多的信息.类 ...
- 10 个迅速提升你 Git 水平的提示(转)
最近我们推出了两个教程:熟悉Git的基本功能和 让你在开发团队中熟练的使用Git . 我们所讨论的命令足够一个开发者在Git使用方面游刃有余.在这篇文章中,我们试图探索怎样有效的管理你的时间和充分的使 ...
- WebService 通过POST方式访问时候,因 URL 意外地以“/方法名”结束,请求格式无法识别 解决办法
因URL意外地以“/方法名”结束,请求格式无法识别. 执行当前Web请求期间生成了未处理的异常.可以使用下面的异常堆栈跟踪信息确定有关异常原因和发生位置的信息. 解决方法:在webservice的we ...
- JDBC/XML的一些基本使用
原文:JDBC/XML的一些基本使用 一.知识点题目:JDBC核心API的使用 关键字:JDBC核心API 内容: 1)加载JDBC驱动: Oracle:Class.forName(“oracle.j ...
- HighChart学习-更新数据data Series与重绘
一:HighChart介绍 基于JQuery的纯JavaScript的图标库,支持各种图表显示,同时还支持Mootools 与Prototype详细版本支持在这里: JQuery 1.3.2 - 1. ...
- 浅析ArrayList,LinkedList的执行效率
以前见过很多文章说这两个东西,感觉自己还是没有深入理解,今天看了书明白一些,在此提出来和大家共同探讨: 面试的时候(基础)一般会问你使用过LinkedList或者ArrayList没有,简单的回答有或 ...
- jquery下php与ajax的数据交换方式
参考链接:http://www.php100.com/html/webkaifa/PHP/PHPyingyong/2013/0122/11971.html 一.前台传递字符串变量,后台返回字符串变量( ...
- duilib底层机制剖析:窗口类与窗口句柄的关联
转载请说明原出处.谢谢~~ 看到群里朋友有人讨论WTL中的thunk技术,让我联想到了duilib的类似技术. 这些技术都是为了解决c++封装的窗口类与窗口句柄的关联问题. 这里是三篇关于thunk技 ...
- 依赖注入(DI)
依赖注入(DI) IoC主要体现了这样一种设计思想:通过将一组通用流程的控制从应用转移到框架之中以实现对流程的复用,同时采用“好莱坞原则”是应用程序以被动的方式实现对流程的定制.我们可以采用若干设 ...