Java远程服务器访问- Telnet VS Jsch

先看看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的测试,此程序仅作测试,所以很多写法并不规范。

   注意: linux默认是使用SSH服务的 而不安装telnet服务,如果要使用telnet 就必须先安装相应的软件包,即使安装了软件包 默认的设置telnet 服务也是不运行的 需要手工进行设置。

   参考:http://www.2cto.com/os/201208/146747.html

    (1)所需包:commons-net-2.2.jar

    (2)代码如下:

  1. package telnet;  
  2. import java.io.IOException;  
  3. import java.io.InputStream;  
  4. import java.io.OutputStream;  
  5. import java.net.SocketException;  
  6. import java.util.regex.Pattern;  
  7. import org.apache.commons.net.telnet.TelnetClient;  
  8. public class Telnet {  
  9.     private TelnetClient telnetClient;  
  10.     private InputStream inputStream;  
  11.     private OutputStream outputStream;  
  12.     private long timeout=30000;//默认超时为30秒  
  13.     /** 
  14.      * 建立telnet连接 
  15.      * @param hostIp 服务器Ip 
  16.      * @param port   端口号  telnet 默认端口号为23 
  17.      * @param userName  登陆账号 
  18.      * @param password 登陆密码 
  19.      * @throws IOException  
  20.      * @throws SocketException  
  21.      */  
  22.     public void connect(String hostIp,int port,String userName,String password) throws SocketException, IOException{  
  23.         telnetClient=new TelnetClient();  
  24.         telnetClient.connect(hostIp, port);  
  25.         inputStream=telnetClient.getInputStream(); //接收服务器消息的输入流  
  26.         outputStream=telnetClient.getOutputStream();     //发送消息到服务器的输出流  
  27.         //连接完毕,服务器就等待客户发送 用户名,然后是密码  
  28.         if(sendLoginInfo(userName,".*PASSWORD:")){//假如发送完用户名后得到的提示符是密码提示符  
  29.             sendLoginInfo(password, "//]//$"); //假如发送密码信息后得到的提示符是命令提示符  
  30.         }  
  31.     }  
  32.     private boolean sendLoginInfo(String info,String regext){  
  33.         Pattern pattern=Pattern.compile(regext);  
  34.         try {  
  35.             outputStream.write((info+"/n").getBytes());  
  36.             outputStream.flush();  
  37.             int i=-1;  
  38.             StringBuilder sb=new StringBuilder();  
  39.             long startTime=System.currentTimeMillis();  
  40.             while(System.currentTimeMillis()-startTime<timeout){       
  41.                 while( (i=(char) inputStream.read())>-1){  
  42.                     if(i==-1){  
  43.                         throw  new IllegalArgumentException("接收不到消息");  
  44.                     }  
  45.                     char ch=(char)i;  
  46.                     if(ch=='/n'||ch=='/r'){ //命令提示符是最后在一行的  
  47.                         sb.delete(0, sb.length());  
  48.                         continue;  
  49.                     }  
  50.                     sb.append((char)ch);  
  51.   
  52.                     if(pattern.matcher(sb.toString()).find()){  
  53.                         return true;  
  54.                     }  
  55.                 }  
  56.             }  
  57.             throw  new IllegalArgumentException("超时收不到提示符");  
  58.         } catch (IOException e) {  
  59.             close();  
  60.             return false;  
  61.         }   
  62.     }  
  63.   
  64.     public String   send(String cmd){  
  65.         if(null==telnetClient||null==inputStream||null==outputStream){  
  66.             throw  new IllegalArgumentException("请先 建立连接 或建立连接失败");  
  67.         }  
  68.         Pattern pattern=Pattern.compile("//]//$");//假如命令提示符为 /$  
  69.         StringBuilder text=new StringBuilder();  
  70.         try {  
  71.             outputStream.write((cmd+"/n").getBytes());  
  72.             outputStream.flush();  
  73.             StringBuilder sb=new StringBuilder();  
  74.             long startTime=System.currentTimeMillis();  
  75.             int i=-1;  
  76.             while(System.currentTimeMillis()-startTime<timeout){       
  77.                 while( (i=inputStream.read())>-1){  
  78.                     if(i==-1){  
  79.                         throw  new IllegalArgumentException("接收不到消息");  
  80.                     }  
  81.                     char ch=(char)i;  
  82.                     text.append(ch);  
  83.                     if(ch=='/n'||ch=='/r'){  
  84.                         sb.delete(0, sb.length());  
  85.                         continue;  
  86.                     }         
  87.                     sb.append(ch);    
  88.                     if(pattern.matcher(sb.toString()).find()){//返回字符流中找到了命令提示符  
  89.                         return text.toString();  
  90.                     }  
  91.                 }  
  92.             }  
  93.             throw  new IllegalArgumentException("超时收不到提示符");  
  94.         } catch (IOException e) {  
  95.             close();  
  96.             return null;  
  97.         }   
  98.     }  
  99.     public void close(){  
  100.         if(null!=null){  
  101.             try {  
  102.                 telnetClient.disconnect();  
  103.             } catch (IOException e) {  
  104.                 e.printStackTrace();  
  105.             }  
  106.         }  
  107.     }  
  108.     public static void main(String[] args) throws SocketException, IOException {  
  109.         Telnet telnet=new Telnet();  
  110.         telnet.connect("ip" , 23, "username", "passowrd");  
  111.         System.out.println(telnet.send("ls"));  
  112.         telnet.close();  
  113.     }  
  114. }  

 

    ssh 的实现和和 telnet 大同小异,差别在于建立连接和释放连接:

    (1)需要包:jsch-0.1.42.jar

    (2) 关键代码如下:

     

[java] view plain copy

  1. /** 
  2.      * 建立连接 
  3.      * @param hostIp 服务器Ip 
  4.      * @param port   ssh端口号 默认为 22 
  5.      * @param userName 
  6.      * @param password 
  7.      */  
  8.     public void connect(String hostIp,int port,String userName,String password){  
  9.         try {  
  10.             session=jsch.getSession(userName,hostIp,port );  
  11.             session.setPassword(password);  
  12.             session.setUserInfo(defaultUserInfo);  
  13.             session.connect();  
  14.             channel=session.openChannel("shell");  
  15.             inputStream=channel.getInputStream();  
  16.             outputStream=channel.getOutputStream();  
  17.         } catch (JSchException e) {  
  18.             // TODO Auto-generated catch block  
  19.             e.printStackTrace();  
  20.         }catch (IOException e) {  
  21.             // TODO Auto-generated catch block  
  22.             e.printStackTrace();  
  23.         }  
  24.     }  
  25.   //关闭连接  
  26.     public void  close(){  
  27.        if(null!=channel){  
  28.            channel.disconnect();  
  29.        }  
  30.        if(null!=session){  
  31.            session.disconnect();  
  32.        }  
  33.     }  

 

 其中 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) {
        }
    }

转载于:https://my.oschina.net/liuyuanyuangogo/blog/699813

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值