遠程連接Telnet

 

     這是一個遠程連接工具,使用的是Apache commons-net.3.3,下面的代碼是自己做的封裝

    

     maven配置如下:

    

<dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.3</version>
</dependency>
<!--這裏是引用了本地的一個jar包,主要服務於WeatherTelnet類-->
<dependency>
            <groupId>commons-net</groupId>
            <artifactId>examples</artifactId>
            <version>3.3</version>
            <scope>system</scope>
            <systemPath>H:\Apache\commons-net\commons-net-examples-3.3.jar</systemPath>
        </dependency>

 

     封裝的Telnet類

package com.special.utils.telnet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.telnet.TelnetClient;

import java.io.*;

/**
 * file TelnetUtil
 * 使用Apache的commons-net 3.3 作爲底層,封裝的一個遠程連接工具包
 * TODO:如果字符串的截取未按理想狀態進行,那麼程序將掛起,所以最好將byte數組設爲一屏的字節
 * @author ds
 * @version 1.0 2015
 *          date 15-3-18
 */
public class TelnetUtil {
    Log log = LogFactory.getLog(TelnetUtil.class);
    /**
     * 終端類型,格式由前綴T_加終端類型構成
     */
    public enum TerminalType {
        T_513, T_715, T_4410, T_4425, T_VT220, T_NTT, T_W2KTT, T_SUNT;

        /**
         * 獲取終端類型的類型名稱
         *
         * @return 實際類型名稱
         */
        public String getTypeName() {
            String name = this.name();
            return name.substring(2, name.length());
        }
    }

    /**
     * 連接失敗後,嘗試重連的次數 _rCnt作爲常量標識
     */
    final Integer _rCnt = 1;
    Integer reCntCount = _rCnt;
    /**
     * 終端輸入用戶名的提示信息
     */
    final String _logPrompt = "login: ";
    /**
     * 終端輸入密碼的提示信息
     */
    final String _pwdPrompt = "Password: ";
    /**
     * 終端選擇終端類型的提示信息
     */
    final String _terPrompt = "[513]";
    /**
     * 終端輸入命令的提示信息
     */
    final String _cmdPrompt = "Command: ";
    /**
     * 客戶端
     */
    TelnetClient client;
    /**
     * 終端類型
     */
    String _terName = "W2KTT";
    /**
     * 遠程輸入流;該處使用過Reader,本來意欲每次讀取一行,
     * 但是實驗結果表示使用reader導致輸出停滯
     */
    InputStream remoteInput;
    /**
     * 遠程輸出流 ,使用該流主要是使用它的println()功能;
     * 他不需要手動加入回車換行,相當於每輸入一次,自動加確認機制
     */
    PrintStream remoteOut;

    /**
     * 構造方法
     *
     * @param host    遠程主機域名或者IP
     * @param port    主機的端口號
     * @param terType 終端類型
     */
    public TelnetUtil(String host, Integer port, TerminalType terType) {
        //開啓客戶端連接
        _terName = terType.getTypeName();
        client = new TelnetClient(_terName);
        //遠程連接
        if (getConnect(host, port)) {
            //設置輸入輸出流
            remoteInput = client.getInputStream();
            remoteOut = new PrintStream(client.getOutputStream());
        } else { //如果連接失敗需要初始化流
            remoteInput = new ByteArrayInputStream("connect failure!".getBytes());
            remoteOut = new PrintStream(new ByteArrayOutputStream());
        }
    }

    /**
     * 獲取遠程連接
     *
     * @param host 主機域名或者IP
     * @param port 主機端口
     * @return boolean true 連接成功 false 連接失敗
     */
    private boolean getConnect(String host, Integer port) {
        boolean flag = false;
        try {
            client.connect(host, port);
            flag = true;
        } catch (IOException e) {
            //嘗試重複連接,此處可以不使用同步,因爲getConnect爲私有非靜態,並且連接次數也是非靜態
            if (!client.isConnected() && reCntCount > 0) {
                reCntCount--;
                if (getConnect(host, port)) {
                    reCntCount = _rCnt;
                    flag = true;
                }
            } else {
                reCntCount = _rCnt;
            }
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 輸入用戶名、密碼登錄終端
     *
     * @param name 用戶名
     * @param pwd  用戶密碼
     */
    public void login(String name, String pwd) {
        //輸入用戶名
        read(_logPrompt);
        write(name);
        //輸入密碼
        read(_pwdPrompt);
        write(pwd);
        //輸入終端信息
        read(_terPrompt);
        write(_terName);
        //讀取可以輸入命令
        read(_cmdPrompt);
    }

    public StringBuffer execCommand(String command,String endBy){
        write(command);
        return readEndBy(endBy);
    }

    /**
     * 讀取流中的數據
     *
     * @param flagWords 流中是否含有該標誌
     * @return String 錯誤則返回error,否則返回讀取的字符串
     */
    public String read(String flagWords) {

        String tmp = null;
        int read ;
        byte[] buff = new byte[2048];
        flagWords = flagWords==null?"":flagWords;
        try {
            while ((read = remoteInput.read(buff))>0) {
                tmp = new String(buff,0,read);
                log.info("#" + tmp + "#");
                /*此處就是潛在的BUG,如果截取的字符串非理想化,那麼這裏程序將掛起,
                可以通過調整byte數組大小來解決,即確認截取一屏的字節數*/
                if (tmp.startsWith(flagWords) || tmp.indexOf(flagWords) > 0) {
                    return tmp;
                }else if(tmp.indexOf("successfully completed")>0){
                    return tmp;
                }
            }
        } catch (IOException e) {
            tmp = "error";
            e.printStackTrace();
        }

        return tmp;
    }

    /**
     * 讀取流中的數據
     *
     * @param end 流中是否含有該標誌
     * @return StringBuffer 錯誤則返回error,否則返回讀取的字符串
     */
    public StringBuffer readEndBy(String end) {

        String tmp ;
        StringBuffer buffer = new StringBuffer();
        int read;
        byte[] bytes = new byte[2048];
        end = end==null?"":end;
        try {
            while (0 < (read = remoteInput.read(bytes))) {
                //替換特殊字符
                tmp = new String(bytes,0,read).replaceAll("\\u001B","");
                buffer.append(tmp);
                log.info("#" + tmp + "#");
                //此處僅適用endsWith是爲了防止相同結束符存在造成的獲取誤差
                if (tmp.endsWith(end)) {
                    return buffer;
                }
            }
        } catch (IOException e) {
            buffer = new StringBuffer();
            buffer.append("error");
            e.printStackTrace();
        }

        return buffer;
    }

    /**
     * 關閉連接
     */
    public void close() {
        //關閉流
        if (null != remoteInput) {
            try {
                remoteInput.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != remoteOut) {
            remoteOut.close();
        }
        //關閉連接
        try {
            client.disconnect();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 往流裏寫入數據
     *
     * @param msg  需要寫入流的數據
     */
    public void write(String msg) {
        remoteOut.println(msg);
        remoteOut.flush();
    }

    public static void main(String[] args) throws IOException, InterruptedException {
        TelnetUtil util = new TelnetUtil("10.11.9.*",5023,TerminalType.T_W2KTT);
        util.login("szct****", "sz****");
        StringBuffer tmp = util.execCommand("status socket-usage","[0m");
        System.out.println(tmp.toString());
        util.close();
    }
}

 

   net中自帶的實例工具類,可以參考下

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.special.utils.telnet;

import java.io.IOException;
import org.apache.commons.net.telnet.TelnetClient;

import examples.util.IOUtil;

/***
 * This is an example of a trivial use of the TelnetClient class.
 * It connects to the weather server at the University of Michigan,
 * um-weather.sprl.umich.edu port 3000, and allows the user to interact
 * with the server via standard input.  You could use this example to
 * connect to any telnet server, but it is obviously not general purpose
 * because it reads from standard input a line at a time, making it
 * inconvenient for use with a remote interactive shell.  The TelnetClient
 * class used by itself is mostly intended for automating access to telnet
 * resources rather than interactive use.
 * <p>
 ***/

// This class requires the IOUtil support class!
public final class WeatherTelnet
{

    public final static void main(String[] args)
    {
        TelnetClient telnet;

        telnet = new TelnetClient();

        try
        {
//            telnet.connect("rainmaker.wunderground.com", 3000);
            telnet.connect("10.11.9.5",5023);
        }
        catch (IOException e)
        {
            e.printStackTrace();
            System.exit(1);
        }

        IOUtil.readWrite(telnet.getInputStream(), telnet.getOutputStream(),
                         System.in, System.out);

        try
        {
            telnet.disconnect();
        }
        catch (IOException e)
        {
            e.printStackTrace();
            System.exit(1);
        }

        System.exit(0);
    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章