4)最后,本地终端对远程主机进行撤消连接。该过程是撤销一个TCP连接。
下面是具体的代码,请借鉴:
import org.apache.commons.net.telnet.TelnetClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class TelnetConnection extends {
private static Logger log = LoggerFactory.getLogger(TelnetConnection.class);
private String ip;
private int port = 23;
private String userName;
private String userPwd;
private String charSet = "GBK";
private TelnetClient client = new TelnetClient("VT220");
private InputStream in;
private PrintStream out;
public TelnetConnection(Map params) {
if (params == null || params.size() == 0) {
throw new IllegalArgumentException(
"Telnet connection params is null");
} else {
this.ip = params.get(ParameterNameList.IPADDRESS.toString());
String port = params.get(ParameterNameList.PORT.toString());
this.port = port == null || port.length() == 0 ? 23 : Integer
.parseInt(port);
this.userName = params.get(ParameterNameList.USERNAME.toString());
this.userPwd = params.get(ParameterNameList.PASSWORD.toString());
this.charSet = params.get(ParameterNameList.CHARSET.toString());
this.charSet = (this.charSet == null || this.charSet.length() == 0) ? "GBK"
: this.charSet;
}
}
@Override
protected void open() throws Exception {
client.connect(ip, port);
in = client.getInputStream();
out = new PrintStream(client.getOutputStream());
/** Log the user on* */
readUntil("\n\rlogin: ", "\n\rLogin: ");
write(userName);
readUntil("\n\rpassword: ", "\n\rPassword: ");
write(userPwd);
StringBuilder sb=new StringBuilder();
while(cmdEnd==null){
ReadResult result = readUntil(1);
sb.append(result.getResult());
if (isLoginFailed(sb.toString())) {
throw new Exception("Login Failed");
}
Thread.sleep(100); //等100毫秒,降低cpu损耗
}
}
private ReadResult readUntil(String... ends) throws Exception {
return readUntil(-1, ends);
}
private ReadResult readUntil(int timeout, String... ends) throws Exception {
ReadResult readResult = new ReadResult();
List sampleList = null;
ByteBuffer compareBuf = null;
boolean enableEndsWithCheck = ends != null && ends.length > 0;
if (enableEndsWithCheck) { // 有结束符时的逻辑
sampleList = new ArrayList();
int maxSampleLength = -1;
for (int c = 0; c < ends.length; c++) { // 创建样本列表
byte[] bytes = ends[c].getBytes(charSet);
maxSampleLength = Math.max(maxSampleLength, bytes.length);
sampleList.add(bytes);
}
compareBuf = ByteBuffer.allocate(maxSampleLength); // 比较缓冲
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
int bufferSize = 1024;
final byte[] buf = new byte[bufferSize]; // BUFSIZE 是一个常量10240=10k
while (true) { // 循化读取
int read;
if (timeout > 0) { // 有超时限制
TimeoutExecution timeoutExecution = new TimeoutExecution() {
@Override
protected Integer execute() throws Exception {
return in.read(buf);
}
};
if (timeoutExecution.execute(timeout, TimeUnit.SECONDS)) {
read = timeoutExecution.getResult(); // 没有超时获得读取的数据长
} else {
// 超时
break;
}
} else { // 无超时限制
read = in.read(buf);
}
if (read != -1) { // 读到数据
outputStream.write(buf, 0, read);
if (enableEndsWithCheck) { // 有结束符时的逻辑
byte[] array = compareBuf.array();
if (read > array.length) {//当新的数据长度大于缓存最大容量时,截取新数据中最后一部分长度为缓存最大容量的数据,最为备选停止标识
compareBuf.clear();
compareBuf.put(buf, read - array.length, array.length); // 将最后数据部分,放入比较缓冲
} else {
int remaining = compareBuf.remaining();
if (remaining >= read) { // 当缓存剩余空间大于新读出数据的长度时,直接写入
compareBuf.put(buf, 0, read);
} else {
/*
* 如果剩余空间小于新读出数据的长度,则需要先从缓存中取出已存数据大小减去新数据大小的数据,
* 这样做的目的是为了避免造成停止结束标识断开。然后将这部分数据和新数据一起重新放入缓存。
*/
int firstPartIndex = array.length - read;
byte[] oldArray = Arrays.copyOfRange(array,
array.length - firstPartIndex, array.length);
compareBuf.clear();// 清空
compareBuf.put(oldArray);
compareBuf.put(buf, 0, read);
}
}
// 开始比较特征
array = compareBuf.array();
int position = compareBuf.position();
boolean matched = false;
for (int exampleIdx = 0; exampleIdx < sampleList.size(); exampleIdx++) {
byte[] sample = sampleList.get(exampleIdx); // 获取样本
if (sample.length <= position) { // 长度一样,进行逐一匹配
int offset = position - sample.length; // 位移
matched = true;
for (int c = 0; c < sample.length; c++) {
if (sample[c] != array[c + offset]) {
matched = false;
break;
}
}
if (matched) { // 匹配
readResult.setMatcher(exampleIdx);// 结果中包含
// example的下标
break; // 跳过其它样本检查
} else {
continue; // 继续其它样本检查
}
} else { // 样本长度大,说明不匹配
continue; // 下一个样本
}
}
if (matched) { // 发现匹配结束符,终止匹配
break;
}
}
} else { // -1没有读到数据,这样情况不太可能被调用到
break;
}
}
readResult.setResult(outputStream.toString(charSet)); // 流中数据统一转码
outputStream.close();
return readResult;
}
public void write(String value) {
try {
out.print(value + "\r\n");
out.flush();
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
}
private String cmdEnd = null;
private boolean isLoginFailed(String result) throws Exception {
boolean isFailed = false;
if (result.length() > 0) {
isFailed = result.contains("ailed");
}
int i = result.lastIndexOf("\r\n");
if (i > 0) {
cmdEnd = result.substring(i); // 获得结束提示符,带回车
if (logger.isDebugEnabled()) {
logger.debug("Prompt Detected! \"{}\"", cmdEnd);
}
}
return isFailed;
}
private class ReadResult {
private int matcher = -1;
private String result = null;
public int getMatcher() {
return matcher;
}
public void setMatcher(int matcher) {
this.matcher = matcher;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("ReadResult{");
sb.append("matcher=").append(matcher);
sb.append(", result='").append(result).append('\'');
sb.append('}');
return sb.toString();
}
}
public CliResult runCmd(String name, String command) {
try {
write(command);
StringBuilder result = new StringBuilder();
ReadResult readResult = readUntil(cmdEnd, "--More--", "--more--");
result.append(readResult.getResult());
while (readResult.getMatcher() != 0) { // "--More--", "--more--"
String moreResult = readResult.getResult();
result.append(moreResult.substring(0, moreResult.length() - 8));
write((char) 32 + "");
readResult = readUntil(cmdEnd, "--More--", "--more--");
}
String[] vals = result.toString().trim().split("\r\n");
List rel = new ArrayList();
if (logger.isDebugEnabled()) {
log.debug("Value For Command " + command + " Is Below:");
}
for (String val : vals) {
if (logger.isDebugEnabled()) {
log.debug(val);
}
rel.add(val);
}
CliResult cliResult = new CliResult(name, command, rel);
return cliResult;
} catch (Exception e) {
log.error("Exec Command Error, Cause " + e.getMessage(), e);
}
return null;
}
@Override
protected void close() {
try {
if (this.in != null) {
this.in.close();
}
if (this.out != null) {
this.out.close();
}
this.client.disconnect();
} catch (Exception e) {
e.printStackTrace();
log.error("Close Telnet Connection Error, cause " + e.getMessage());
}
}
@Override
protected boolean validate() {
return client.isAvailable();
}
public static void main(String args[]) {
Map params = new HashMap();
params.put(ParameterNameList.IPADDRESS.toString(), "127.0.0.1");
params.put(ParameterNameList.USERNAME.toString(), "Administrator");
params.put(ParameterNameList.PASSWORD.toString(), "XXXXXX");
params.put(ParameterNameList.PORT.toString(), "23");
TelnetConnection telCon = new TelnetConnection(params);
try {
telCon.open();
CliResult val = telCon.runCmd("Windows", "systeminfo");
List vals = val.getResult();
int i = 1;
for (String str : vals) {
System.out.println(i + " " + str);
i++;
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
telCon.close();
}
}
}