首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 實作 Telnet Client 工具類 (基於 Apache Commons Net)

     編輯:Java 相關知識

Java 實作 Telnet Client 工具類 (基於 Apache Commons Net)

Telnet 協議雖老舊但仍廣泛用於網路設備管理、舊系統整合。Apache Commons Net 提供 TelnetClient 封裝協議細節。本文封裝一個可重用的 TelnetUtil 類別,支援連線、登入、指令執行、編碼設定與資源釋放。

Maven 依賴

<dependency>
    <groupId>commons-net</groupId>
    <artifactId>commons-net</artifactId>
    <version>3.9.0</version> <!-- 最新版本 -->
</dependency>

核心類別設計

public class TelnetUtil {
    private String charset = "UTF-8";
    private byte[] buffer = new byte[2048];
    private TelnetClient client = new TelnetClient();
    private BufferedReader reader;
    private BufferedWriter writer;
    private InputStream in;
    private OutputStream out;

    // 連線 (預設埠 23)
    public void connect(String ip, int port) throws IOException {
        client.connect(ip, port);
        initStreams();
    }
    public void connect(String ip) throws IOException { connect(ip, 23); }

    private void initStreams() throws UnsupportedEncodingException {
        in = client.getInputStream();
        out = client.getOutputStream();
        reader = new BufferedReader(new InputStreamReader(in, charset));
        writer = new BufferedWriter(new OutputStreamWriter(out, charset));
    }

    // 登入流程 (自動處理 login:/Password: 提示)
    public boolean login(String user, String pass) throws IOException {
        String line = readUntil("login:");
        writer.write(user + "\r\n"); writer.flush();
        line = readUntil("Password:");
        writer.write(pass + "\r\n"); writer.flush();
        line = readUntil("Last login:", "incorrect");
        return line.contains("Last login:");
    }

    // 執行指令並回傳輸出
    public String exec(String cmd) throws IOException {
        writer.write(cmd + "\r\n"); writer.flush();
        return readUntilPrompt(); // 需依目標系統提示符調整
    }

    // 讀取直到關鍵字出現
    private String readUntil(String... keywords) throws IOException {
        StringBuilder sb = new StringBuilder();
        while (true) {
            String line = reader.readLine();
            if (line == null) break;
            sb.append(line).append("\n");
            for (String kw : keywords) if (line.contains(kw)) return sb.toString();
        }
        return sb.toString();
    }

    // 關閉資源
    public void close() {
        try { writer.write("exit\r\n"); writer.flush(); } catch (Exception ignored) {}
        closeQuietly(in); closeQuietly(out); 
        try { client.disconnect(); } catch (Exception ignored) {}
    }
    private void closeQuietly(Closeable c) { try { if (c != null) c.close(); } catch (Exception ignored) {} }

    // 設定編碼 (需在 connect 前呼叫)
    public void setCharset(String cs) { this.charset = cs; }
    public void setBufferSize(int size) { this.buffer = new byte[size]; }
}

使用範例

public static void main(String[] args) {
    TelnetUtil telnet = new TelnetUtil();
    telnet.setCharset("UTF-8"); // 依伺服器編碼調整
    try {
        telnet.connect("192.168.1.1", 23);
        if (telnet.login("admin", "password")) {
            System.out.println("登入成功");
            String output = telnet.exec("show version");
            System.out.println("指令輸出:\n" + output);
        } else {
            System.err.println("登入失敗");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        telnet.close();
    }
}

關鍵實作細節

  • 提示符處理:不同設備 (Cisco, Linux, Huawei) 提示符差異大 (#, >, $),readUntilPrompt() 需客製化。
  • 編碼問題:中文環境常見 GBK/Big5,必須 setCharset() 對應,否則會亂碼。
  • 同步讀取:範例採用阻塞式 readLine(),高併發場景建議改用非阻塞 I/O 或獨立執行緒讀取。
  • 替代方案:SSH (JSch, Apache MINA SSHD) 更安全,新專案優先考慮 SSH。

常見問題排查

  1. 連線逾時:檢查防火牆、ACL、Telnet 服務是否啟用 (port 23)。
  2. 登入失敗:確認使用者名稱大小寫、密碼特殊字元、提示字串是否為 login:/Password: (某些設備為 Username:)。
  3. 指令無回應:可能需送 \r 或 \r\n,或指令需進入特定模式 (如 enable、configure terminal)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved