先看看telnet 和ssh的定義:html
Telnet協議是TCP/IP協議中的一員,是Internet遠程登錄服務的標準協議和主要方式。它爲用戶提供了在本地計算機上完成遠程主機工做的能力。在終端使用者的電腦上使用telnet程序,用它鏈接到服務器。終端使用者能夠在telnet程序中輸入命令,這些命令會在服務器上運行,就像直接在服務器的控制檯上輸入同樣。能夠在本地就能控制服務器。要開始一個telnet會話,必須輸入用戶名和密碼來登陸服務器。Telnet是經常使用的遠程控制Web服務器的方法。java
SSH是一個用來替代TELNET、FTP以及R命令的工具包,主要是想解決口令在網上明文傳輸的問題。爲了系統安全和用戶自身的權益,推廣SSH是必要的。 SSH是英文Secure Shell的簡寫形式。經過使用SSH,你能夠把全部傳輸的數據進行加密,這樣"中間人"這種攻擊方式就不可能實現了,並且也可以防止DNS欺騙和IP欺騙。linux
實際上,telnet和ssh的功能基本相同,都是實現遠程登錄的網絡協議。shell
和其餘多數協議同樣, Java 中telnet ssh的實現也要通過三部曲:創建鏈接、使用鏈接 和釋放鏈接 。ssh是用以替換telnet 的一種協議,在java 編程中 ,ssh和telnet 的不一樣僅僅表如今創建鏈接和釋放鏈接中。apache
使用鏈接的過程,其實就是發送命令和遠程服務器交互的過程,原理也很簡單:每向服務器發送一條命令,就等待服務器執行此命令後返回的字符流,暫且把它叫作一次交互。咱們以在規定時間內接收這些字符流,若是這些字符流中出現了「命令提示符」,說明服務器處於等待狀態,咱們就認爲這次交互完成,不然,這次交互失敗,出現異常。編程
linux服務器上的命令提示符很少,登錄命令提示符就更有限了,通常就包括 用戶名提示符、密碼提示符 和登錄成功提示符(也叫命令提示符)這三類,不一樣linux的用戶命令提示符、密碼提示符也會稍有不一樣。安全
下面簡單寫一個程序作telnet的測試,此程序僅做測試,因此不少寫法並不規範。服務器
注意: linux默認是使用SSH服務的 而不安裝telnet服務,若是要使用telnet 就必須先安裝相應的軟件包,即便安裝了軟件包 默認的設置telnet 服務也是不運行的 須要手工進行設置。網絡
參考:http://www.2cto.com/os/201208/146747.htmlsession
(1)所需包:commons-net-2.2.jar
(2)代碼以下:
ssh 的實現和和 telnet 大同小異,差異在於創建鏈接和釋放鏈接:
(1)須要包:jsch-0.1.42.jar
(2) 關鍵代碼以下:
[java] view plain copy
其中 defaultUserInfo 是實現了UserInfo的一個類對象:
[java] view plain copy
先看看telnet 和ssh的定義:
Telnet協議是TCP/IP協議中的一員,是Internet遠程登錄服務的標準協議和主要方式。它爲用戶提供了在本地計算機上完成遠程主機工做的能力。在終端使用者的電腦上使用telnet程序,用它鏈接到服務器。終端使用者能夠在telnet程序中輸入命令,這些命令會在服務器上運行,就像直接在服務器的控制檯上輸入同樣。能夠在本地就能控制服務器。要開始一個telnet會話,必須輸入用戶名和密碼來登陸服務器。Telnet是經常使用的遠程控制Web服務器的方法。
SSH是一個用來替代TELNET、FTP以及R命令的工具包,主要是想解決口令在網上明文傳輸的問題。爲了系統安全和用戶自身的權益,推廣SSH是必要的。 SSH是英文Secure Shell的簡寫形式。經過使用SSH,你能夠把全部傳輸的數據進行加密,這樣"中間人"這種攻擊方式就不可能實現了,並且也可以防止DNS欺騙和IP欺騙。
實際上,telnet和ssh的功能基本相同,都是實現遠程登錄的網絡協議。
和其餘多數協議同樣, Java 中telnet ssh的實現也要通過三部曲:創建鏈接、使用鏈接 和釋放鏈接 。ssh是用以替換telnet 的一種協議,在java 編程中 ,ssh和telnet 的不一樣僅僅表如今創建鏈接和釋放鏈接中。
使用鏈接的過程,其實就是發送命令和遠程服務器交互的過程,原理也很簡單:每向服務器發送一條命令,就等待服務器執行此命令後返回的字符流,暫且把它叫作一次交互。咱們以在規定時間內接收這些字符流,若是這些字符流中出現了「命令提示符」,說明服務器處於等待狀態,咱們就認爲這次交互完成,不然,這次交互失敗,出現異常。
linux服務器上的命令提示符很少,登錄命令提示符就更有限了,通常就包括 用戶名提示符、密碼提示符 和登錄成功提示符(也叫命令提示符)這三類,不一樣linux的用戶命令提示符、密碼提示符也會稍有不一樣。
下面簡單寫一個程序作telnet的測試,此程序僅做測試,因此不少寫法並不規範。
(1)所需包:commons-net-2.2.jar
(2)代碼以下:
package telnet;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.util.regex.Pattern;
import org.apache.commons.net.telnet.TelnetClient;
public class Telnet {
private TelnetClient telnetClient;
private InputStream inputStream;
private OutputStream outputStream;
private long timeout=30000;//默認超時爲30秒
/**
* 創建telnet鏈接
* @param hostIp 服務器Ip
* @param port 端口號 telnet 默認端口號爲23
* @param userName 登錄帳號
* @param password 登錄密碼
* @throws IOException
* @throws SocketException
*/
public void connect(String hostIp,int port,String userName,String password) throws SocketException, IOException{
telnetClient=new TelnetClient();
telnetClient.connect(hostIp, port);
inputStream=telnetClient.getInputStream(); //接收服務器消息的輸入流
outputStream=telnetClient.getOutputStream(); //發送消息到服務器的輸出流
//鏈接完畢,服務器就等待客戶發送 用戶名,而後是密碼
if(sendLoginInfo(userName,".*PASSWORD:")){//假如發送完用戶名後獲得的提示符是密碼提示符
sendLoginInfo(password, "//]//$"); //假如發送密碼信息後獲得的提示符是命令提示符
}
}
private boolean sendLoginInfo(String info,String regext){
Pattern pattern=Pattern.compile(regext);
try {
outputStream.write((info+"/n").getBytes());
outputStream.flush();
int i=-1;
StringBuilder sb=new StringBuilder();
long startTime=System.currentTimeMillis();
while(System.currentTimeMillis()-startTime<timeout){
while( (i=(char) inputStream.read())>-1){
if(i==-1){
throw new IllegalArgumentException("接收不到消息");
}
char ch=(char)i;
if(ch=='/n'||ch=='/r'){ //命令提示符是最後在一行的
sb.delete(0, sb.length());
continue;
}
sb.append((char)ch);
if(pattern.matcher(sb.toString()).find()){
return true;
}
}
}
throw new IllegalArgumentException("超時收不到提示符");
} catch (IOException e) {
close();
return false;
}
}
public String send(String cmd){
if(null==telnetClient||null==inputStream||null==outputStream){
throw new IllegalArgumentException("請先 創建鏈接 或創建鏈接失敗");
}
Pattern pattern=Pattern.compile("//]//$");//假如命令提示符爲 /$
StringBuilder text=new StringBuilder();
try {
outputStream.write((cmd+"/n").getBytes());
outputStream.flush();
StringBuilder sb=new StringBuilder();
long startTime=System.currentTimeMillis();
int i=-1;
while(System.currentTimeMillis()-startTime<timeout){
while( (i=inputStream.read())>-1){
if(i==-1){
throw new IllegalArgumentException("接收不到消息");
}
char ch=(char)i;
text.append(ch);
if(ch=='/n'||ch=='/r'){
sb.delete(0, sb.length());
continue;
}
sb.append(ch);
if(pattern.matcher(sb.toString()).find()){//返回字符流中找到了命令提示符
return text.toString();
}
}
}
throw new IllegalArgumentException("超時收不到提示符");
} catch (IOException e) {
close();
return null;
}
}
public void close(){
if(null!=null){
try {
telnetClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws SocketException, IOException {
Telnet telnet=new Telnet();
telnet.connect("ip" , 23, "username", "passowrd");
System.out.println(telnet.send("ls"));
telnet.close();
}
}
ssh 的實現 和 telnet 大同小異,差異在於創建鏈接和釋放鏈接:
(1)須要包:jsch-0.1.42.jar
(2) 關鍵代碼以下:
/**
* 創建鏈接
* @param hostIp 服務器Ip
* @param port ssh端口號 默認爲 22
* @param userName
* @param password
*/
public void connect(String hostIp,int port,String userName,String password){
try {
session=jsch.getSession(userName,hostIp,port );
session.setPassword(password);
session.setUserInfo(defaultUserInfo);
session.connect();
channel=session.openChannel("shell");
inputStream=channel.getInputStream();
outputStream=channel.getOutputStream();
} catch (JSchException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//關閉鏈接
public void close(){
if(null!=channel){
channel.disconnect();
}
if(null!=session){
session.disconnect();
}
}
其中 defaultUserInfo 是實現了UserInfo的一個類對象:
UserInfo defaultUserInfo = new UserInfo() { public String getPassphrase() { return null; } public String getPassword() { return null; } public boolean promptPassword(String arg0) { return false; } public boolean promptPassphrase(String arg0) { return false; } public boolean promptYesNo(String arg0) { return true; } public void showMessage(String arg0) { } }