Java使用telnet連接遠程計算機執行命令
所需的jar包 http://commons.apache.org/proper/commons-net/
如題,代碼如下:
package securecrt.ssh2;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.net.telnet.TelnetClient;
/**
*
* 使用java連接telnet進行操作的注意
1.telnet有VT100 VT52 VT220 VTNT ANSI等協議。
我用vt100。
2.vt100控制碼(ansi控制碼)過濾的問題,可以過濾,也可以在服務設置不要。
不過濾都是一些亂碼。是以\033[***一個字母結尾的格式。
3.中文亂碼的問題。
new String(old.getBytes("ISO8859-1"),"GBK")。
4.如何判斷讀取到最後了。
一有readUntil(),二有使用線程。
5.選擇telnet的java包問題,包有很多,比如appache(commons-net-3.1.jar), ganymed(ganymed-ssh2-build210.jar),javaexpect(smart-0.1-SNAPSHOT-jar-with-dependencies.jar)
我使用appache。javaexpect有帶的vt100控制碼過濾,我沒有仔細研究。
6.write要flush()才發送。
*
*
* telnet操作類。使用appache的net.Telnet包,對vt100控制代碼(即ansi控制碼)進行簡單過濾。
*
* @author chruan
* @version 1.0
*/
public class TelnetHelper_bak {
Object lock = new Object();
TelnetClient telnet = null;
String hostname;
int hostport = 23;
String user;
String password;
private InputStream in;
private PrintStream out;
private static final String ORIG_CODEC = "ISO8859-1";
private static final String TRANSLATE_CODEC = "GBK";
public TelnetHelper_bak(String hostname, int hostport, String user,
String password) throws SocketException, IOException {
super();
this.hostname = hostname;
this.hostport = hostport;
this.user = user;
this.password = password;
telnet = new TelnetClient("VT100");// VT100 VT52 VT220 VTNT ANSI
telnet.connect(hostname, hostport);
in = telnet.getInputStream();
out = new PrintStream(telnet.getOutputStream());
readUntil("login: ");
write(user);
write("\n");
readUntil("Password: ");
write(password);
write("\n");
}
private void restartTerminal() {
try {
readUntil(">");
write("telnet 0.0.7.74\n");
readUntil("login: ");
write("dd\n", 500);
readToEnd();
write("dff\n", 200);
readToEnd();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
public void readToEnd() {
ReadThread readThread = new ReadThread();
readThread.start();
try {
readThread.join();
} catch (Exception e) {
}
readThread = null;
}
public void readUntil(String str) {
char last = str.charAt(str.length() - 1);
String[] ss;
try {
StringBuffer sb = new StringBuffer();
char c;
int code = -1;
boolean ansiControl = false;
boolean start = true;
while ((code = (in.read())) != -1) {
c = (char) code;
if (c == '\033') {//vt100控制碼都是以\033開頭的。
ansiControl = true;
int code2 = in.read();
char cc = (char) code2;
if (cc == '[' || cc == '(') {
}
}
if (!ansiControl) {
if (c == '\r') {
//這裡是命令行中的每一句反饋
String olds = new String(sb.toString().getBytes(
ORIG_CODEC), TRANSLATE_CODEC);
System.out.println(olds);
if (sb.lastIndexOf(str) != -1) {
break;
}
sb.delete(0, sb.length());
} else if (c == '\n')
;
else
sb.append(c);
if (sb.lastIndexOf(str) != -1) {
break;
}
}
if (ansiControl) {
if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
|| c == '"') {
ansiControl = false;
}
}
}
System.out.println(new String(sb.toString().getBytes(ORIG_CODEC),
TRANSLATE_CODEC));
} catch (Exception e) {
e.printStackTrace();
}
}
public void write(String s) {
try {
out.write(s.getBytes());
out.flush();
System.out.println(s);
} catch (Exception e) {
}
}
public void write(String s, int sleep) {
write(s);
try {
Thread.sleep(sleep);
} catch (Exception e) {
}
}
/**
* 完成之後必須關閉
*/
public void close() {
if (out != null)
out.close();
if (in != null)
try {
in.close();
} catch (IOException e1) {
}
if (telnet != null)
try {
telnet.disconnect();
} catch (IOException e) {
}
}
public void doJob() {
// restartTerminal();
counter();
}
private void counter() {
//演示在一台機器上遠程登錄另一台計算機
try {
readUntil("bash-2.05b$ ");
write("ssh [email protected]\n");
readUntil("[email protected]'s password: ");
write("nodee\n");
readUntil("[nodee@dz-05 ~]$ ");
write("ll\n");
readToEnd();
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}
public static void main(String[] args) {
String hostname = "192.168.0.2";
int hostport = 23;
String user = "username";
String password = "pwd";
TelnetHelper_bak helper = null;
try {
helper = new TelnetHelper_bak(hostname, hostport, user, password);
helper.doJob();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (helper != null)
helper.close();
}
}
/**
* 讀取主線程,負責管理子線程。防止讀取時不動了,這時就拋棄讀取子線程
*
*/
class ReadThread extends Thread {
public void run() {
synchronized (lock) {//只能一個讀取
SubReadThread sub = new SubReadThread();
sub.start();
int last = sub.count;
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
if (last == sub.count) {
sub.stop();
break;
} else {
last = sub.count;
}
}
String s = sub.sb.toString();
try {
System.out.println(new String(s.getBytes(ORIG_CODEC),
TRANSLATE_CODEC));
} catch (UnsupportedEncodingException e) {
System.out.println(s);
}
sub = null;
}
// System.out.println("===========ReadThread end=============");
}
}
/**
* 讀取子線程,完成實際讀取
*
*/
class SubReadThread extends Thread {
int count = 0;
StringBuffer sb = new StringBuffer();
public void read() {
try {
char c;
int code = -1;
boolean ansiControl = false;
boolean start = true;
while ((code = (in.read())) != -1) {
count++;
c = (char) code;
if (c == '\033') {
ansiControl = true;
int code2 = in.read();
char cc = (char) code2;
count++;
if (cc == '[' || cc == '(') {
}
}
if (!ansiControl) {
if (c == '\r') {
String olds = new String(sb.toString().getBytes(
ORIG_CODEC), TRANSLATE_CODEC);
System.out.println(olds);
sb.delete(0, sb.length());
} else if (c == '\n')
;
else
sb.append(c);
}
if (ansiControl) {
if (('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
|| c == '"') {
ansiControl = false;
}
}
}
} catch (Exception e) {
}
}
public void run() {
read();
}
}
}