Java编写Telnet客户端,连接到Windows的Telnet服务器,执行命令和批处理脚本,同时解决了中文乱码的问题。
源代码和Jar包在这里下载:http://download.csdn.net/detail/kerafan/9327585
引入的Jar包:Apache common-net-3.3.jar
工具类代码如下:
package util.telnet;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import org.apache.commons.net.telnet.TelnetClient;
/**
* Telnet 客户端,用于连接Windows的Telnet服务器
*
* @author Lijinsheng
*
* @since 2015-12-04
*
*/
public class WindowsTelnetClient {
/** Telnet服务器返回的字符集 */
private static final String SRC_CHARSET = "ISO8859-1";
/** 转换后的字符集 */
private static final String DEST_CHARSET = "GBK";
/**
* 终端类型。包括以下类型:VT102、VT100、VT220、WYSE50、WYSE60、XTERM、SCOANSI、ANSI、LINUX、
* VSHELL几种。经测试,对于Windows的Telnet服务器,只有VT100、ANSI类型会造成中文乱码
*/
private static final String TERM_TYPE = "VT220";
private TelnetClient client = new TelnetClient(TERM_TYPE);// Telnet客户端
private InputStream input; // Telnet输入流,用于获取Telnet服务器的返回信息
private OutputStream output; // Telnet输出流,用于向服务器发送命令
private String hostname; // IP地址或主机名
private int port = 23; // 端口。默认为23
private String username; // 用户名
private String password; // 密码
private String prompt; // 命令提示符,用于判断是否读取到了返回信息的结尾
/**
* 创建Telnet客户端,用于连接Windows的Telnet服务器。使用默认端口:23
*
* @param hostname
* - IP地址,或主机名
* @param username
* - 用户名
* @param password
* - 密码
*/
public WindowsTelnetClient(String hostname, String username, String password) {
this.hostname = hostname;
this.username = username;
this.password = password;
}
/**
* 创建Telnet客户端,用于连接Windows的Telnet服务器
*
* @param hostname
* - IP地址,或主机名
* @param port
* - 端口
* @param username
* - 用户名
* @param password
* - 密码
*/
public WindowsTelnetClient(String hostname, int port, String username, String password) {
this.hostname = hostname;
this.port = port;
this.username = username;
this.password = password;
}
/**
* 连接到Telnet服务器
*
* @return - Telnet服务器的返回信息。截止到password:
* @throws SocketException
* @throws IOException
*/
public String connect() throws SocketException, IOException {
client.connect(hostname, port);
input = client.getInputStream();
output = client.getOutputStream();
// 因为不知道服务器返回的是Login: 还是 login: ,所以忽略l
String loginOutput = readTo("ogin: ");
output.write((username + "\r\n").getBytes());
output.flush();
// 因为不知道服务器返回的是Password: 还是 password: ,所以忽略p
String passwordOutput = readTo("assword: ");
output.write((password + "\r\n").getBytes());
output.flush();
String promptOutput = readTo(">");
// 取倒数4位字符作为提示符,因为提示符最短为4位,如:C:\>
prompt = promptOutput.substring(promptOutput.length() - 4);
return loginOutput + passwordOutput + password + promptOutput;
}
/**
* 向Telnet服务器发送命令
*
* @param command
* - 命令
* @return - 执行命令后,在命令行输出的信息
* @throws IOException
*/
public String sendCommand(String command) throws IOException {
output.write(command.getBytes());
output.write('\r');
output.write('\n');
output.flush();
return readToPrompt();
}
/**
* 断开连接
*
* @return - 断开连接的命令
*/
public String disconnect() {
try {
input.close();
output.close();
client.disconnect();
} catch (Exception e) {
}
return "exit";
}
/**
* 读取后指定的字符处
*
* @param end
* - 指定的字符
* @return - 从上次读取的位置,到<code>end</code>位置的输出内容
*/
private String readTo(String end) {
StringBuffer sb = new StringBuffer();
char endChar = end.charAt(end.length() - 1);
char chr;
try {
while (true) {
chr = (char) input.read();
sb.append(chr);
if (chr == endChar && sb.toString().endsWith(end)) {
return new String(sb.toString().getBytes(SRC_CHARSET), DEST_CHARSET); // 编码转换,解决中文乱码问题
}
}
} catch (IOException e) {
e.printStackTrace();
}
return "";
}
/**
* 读取后命令提示符
*
* @return - 从上次读取的位置,到命令提示符的输出内容
*/
private String readToPrompt() {
return readTo(prompt);
}
}
测试类的代码如下:
package util.telnet;
public class ClientTest {
public static void main(String[] args) throws Exception {
String hostname = "localhost"; // or:127.0.0.1
int port = 23;
String username = "Lijinsheng";
String password = "abc123";
WindowsTelnetClient client = new WindowsTelnetClient(hostname, port, username, password);
System.out.print(client.connect());
System.out.print(client.sendCommand("dir")); // 执行windows命令
System.out.print(client.sendCommand("D:\\Temp\\bat\\demo.bat abc123")); // 执行批处理脚本
System.out.print(client.disconnect());
}
}
输出结果如下:
Welcome to Microsoft Telnet Service
login: Lijinsheng
password: abc123
*===============================================================
Microsoft Telnet Server.
*===============================================================
C:\Users\Administrator>dir
驱动器 C 中的卷没有标签。
卷的序列号是 ACA6-9BB8
C:\Users\Administrator 的目录
2015-11-22 15:02 <DIR> .
2015-11-22 15:02 <DIR> ..
2015-11-29 15:11 <DIR> .android
2015-08-04 16:14 <DIR> .FontForge
2015-10-15 19:36 <DIR> .IdeaIC14
2015-11-22 15:09 <DIR> .idlerc
2014-10-26 18:02 <DIR> .jmc
2015-07-07 23:06 <DIR> .julia
2015-10-28 11:41 <DIR> .kettle
2015-08-25 10:27 <DIR> .pentaho
2015-08-25 10:26 <DIR> .swt
2014-11-08 22:54 <DIR> CMB
2014-10-22 15:45 <DIR> Contacts
2015-12-04 17:40 <DIR> Desktop
2015-11-26 22:33 <DIR> Documents
2015-02-06 22:12 <DIR> Downloads
2015-06-23 20:23 <DIR> Favorites
2015-03-18 11:56 <DIR> Links
2014-10-22 15:45 <DIR> Music
2014-10-29 10:35 <DIR> Oracle
2014-12-11 12:31 <DIR> Pictures
2014-10-22 15:45 <DIR> Saved Games
2014-10-30 22:36 <DIR> Searches
2015-06-07 20:52 <DIR> Videos
2015-10-28 15:35 1,151 桌面 - 快捷方式.lnk
1 个文件 1,151 字节
24 个目录 88,712,892,416 可用字节
C:\Users\Administrator>D:\Temp\bat\demo.bat abc123
OUT1=abc123
ERROR_CODE=0
ERROR_MSG=SUCCESS..
OUT2=12.345
OUT3=ABC123
OUT4=2015-12-13
C:\Users\Administrator>exit