这是一个远程连接工具,使用的是Apache commons-net.3.3,下面的代码是自己做的封装
maven配置如下:
<dependency> <groupId>commons-net</groupId> <artifactId>commons-net</artifactId> <version>3.3</version> </dependency> <!--这里是引用了本地的一个jar包,主要服务于WeatherTelnet类--> <dependency> <groupId>commons-net</groupId> <artifactId>examples</artifactId> <version>3.3</version> <scope>system</scope> <systemPath>H:\Apache\commons-net\commons-net-examples-3.3.jar</systemPath> </dependency>
封装的Telnet类
package com.special.utils.telnet;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.telnet.TelnetClient;
import java.io.*;
/**
* file TelnetUtil
* 使用Apache的commons-net 3.3 作为底层,封装的一个远程连接工具包
* TODO:如果字符串的截取未按理想状态进行,那么程序将挂起,所以最好将byte数组设为一屏的字节
* @author ds
* @version 1.0 2015
* date 15-3-18
*/
public class TelnetUtil {
Log log = LogFactory.getLog(TelnetUtil.class);
/**
* 终端类型,格式由前缀T_加终端类型构成
*/
public enum TerminalType {
T_513, T_715, T_4410, T_4425, T_VT220, T_NTT, T_W2KTT, T_SUNT;
/**
* 获取终端类型的类型名称
*
* @return 实际类型名称
*/
public String getTypeName() {
String name = this.name();
return name.substring(2, name.length());
}
}
/**
* 连接失败后,尝试重连的次数 _rCnt作为常量标识
*/
final Integer _rCnt = 1;
Integer reCntCount = _rCnt;
/**
* 终端输入用户名的提示信息
*/
final String _logPrompt = "login: ";
/**
* 终端输入密码的提示信息
*/
final String _pwdPrompt = "Password: ";
/**
* 终端选择终端类型的提示信息
*/
final String _terPrompt = "[513]";
/**
* 终端输入命令的提示信息
*/
final String _cmdPrompt = "Command: ";
/**
* 客户端
*/
TelnetClient client;
/**
* 终端类型
*/
String _terName = "W2KTT";
/**
* 远程输入流;该处使用过Reader,本来意欲每次读取一行,
* 但是实验结果表示使用reader导致输出停滞
*/
InputStream remoteInput;
/**
* 远程输出流 ,使用该流主要是使用它的println()功能;
* 他不需要手动加入回车换行,相当于每输入一次,自动加确认机制
*/
PrintStream remoteOut;
/**
* 构造方法
*
* @param host 远程主机域名或者IP
* @param port 主机的端口号
* @param terType 终端类型
*/
public TelnetUtil(String host, Integer port, TerminalType terType) {
//开启客户端连接
_terName = terType.getTypeName();
client = new TelnetClient(_terName);
//远程连接
if (getConnect(host, port)) {
//设置输入输出流
remoteInput = client.getInputStream();
remoteOut = new PrintStream(client.getOutputStream());
} else { //如果连接失败需要初始化流
remoteInput = new ByteArrayInputStream("connect failure!".getBytes());
remoteOut = new PrintStream(new ByteArrayOutputStream());
}
}
/**
* 获取远程连接
*
* @param host 主机域名或者IP
* @param port 主机端口
* @return boolean true 连接成功 false 连接失败
*/
private boolean getConnect(String host, Integer port) {
boolean flag = false;
try {
client.connect(host, port);
flag = true;
} catch (IOException e) {
//尝试重复连接,此处可以不使用同步,因为getConnect为私有非静态,并且连接次数也是非静态
if (!client.isConnected() && reCntCount > 0) {
reCntCount--;
if (getConnect(host, port)) {
reCntCount = _rCnt;
flag = true;
}
} else {
reCntCount = _rCnt;
}
e.printStackTrace();
}
return flag;
}
/**
* 输入用户名、密码登录终端
*
* @param name 用户名
* @param pwd 用户密码
*/
public void login(String name, String pwd) {
//输入用户名
read(_logPrompt);
write(name);
//输入密码
read(_pwdPrompt);
write(pwd);
//输入终端信息
read(_terPrompt);
write(_terName);
//读取可以输入命令
read(_cmdPrompt);
}
public StringBuffer execCommand(String command,String endBy){
write(command);
return readEndBy(endBy);
}
/**
* 读取流中的数据
*
* @param flagWords 流中是否含有该标志
* @return String 错误则返回error,否则返回读取的字符串
*/
public String read(String flagWords) {
String tmp = null;
int read ;
byte[] buff = new byte[2048];
flagWords = flagWords==null?"":flagWords;
try {
while ((read = remoteInput.read(buff))>0) {
tmp = new String(buff,0,read);
log.info("#" + tmp + "#");
/*此处就是潜在的BUG,如果截取的字符串非理想化,那么这里程序将挂起,
可以通过调整byte数组大小来解决,即确认截取一屏的字节数*/
if (tmp.startsWith(flagWords) || tmp.indexOf(flagWords) > 0) {
return tmp;
}else if(tmp.indexOf("successfully completed")>0){
return tmp;
}
}
} catch (IOException e) {
tmp = "error";
e.printStackTrace();
}
return tmp;
}
/**
* 读取流中的数据
*
* @param end 流中是否含有该标志
* @return StringBuffer 错误则返回error,否则返回读取的字符串
*/
public StringBuffer readEndBy(String end) {
String tmp ;
StringBuffer buffer = new StringBuffer();
int read;
byte[] bytes = new byte[2048];
end = end==null?"":end;
try {
while (0 < (read = remoteInput.read(bytes))) {
//替换特殊字符
tmp = new String(bytes,0,read).replaceAll("\\u001B","");
buffer.append(tmp);
log.info("#" + tmp + "#");
//此处仅适用endsWith是为了防止相同结束符存在造成的获取误差
if (tmp.endsWith(end)) {
return buffer;
}
}
} catch (IOException e) {
buffer = new StringBuffer();
buffer.append("error");
e.printStackTrace();
}
return buffer;
}
/**
* 关闭连接
*/
public void close() {
//关闭流
if (null != remoteInput) {
try {
remoteInput.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != remoteOut) {
remoteOut.close();
}
//关闭连接
try {
client.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 往流里写入数据
*
* @param msg 需要写入流的数据
*/
public void write(String msg) {
remoteOut.println(msg);
remoteOut.flush();
}
public static void main(String[] args) throws IOException, InterruptedException {
TelnetUtil util = new TelnetUtil("10.11.9.*",5023,TerminalType.T_W2KTT);
util.login("szct****", "sz****");
StringBuffer tmp = util.execCommand("status socket-usage","[0m");
System.out.println(tmp.toString());
util.close();
}
}
net中自带的实例工具类,可以参考下
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.special.utils.telnet;
import java.io.IOException;
import org.apache.commons.net.telnet.TelnetClient;
import examples.util.IOUtil;
/***
* This is an example of a trivial use of the TelnetClient class.
* It connects to the weather server at the University of Michigan,
* um-weather.sprl.umich.edu port 3000, and allows the user to interact
* with the server via standard input. You could use this example to
* connect to any telnet server, but it is obviously not general purpose
* because it reads from standard input a line at a time, making it
* inconvenient for use with a remote interactive shell. The TelnetClient
* class used by itself is mostly intended for automating access to telnet
* resources rather than interactive use.
* <p>
***/
// This class requires the IOUtil support class!
public final class WeatherTelnet
{
public final static void main(String[] args)
{
TelnetClient telnet;
telnet = new TelnetClient();
try
{
// telnet.connect("rainmaker.wunderground.com", 3000);
telnet.connect("10.11.9.5",5023);
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
IOUtil.readWrite(telnet.getInputStream(), telnet.getOutputStream(),
System.in, System.out);
try
{
telnet.disconnect();
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
System.exit(0);
}
}