Web_telnet 通過JAVA實現網頁上面的命令行遠程工具 以及對於流的理解


 

前言

這幾天研究了一下如何在web頁面上通過telnet 連接一個遠程的機器,通過命令行進行控制,讓然,B/S架構的項目,如果直接通過

瀏覽器是無法和遠程機器進行通信的,我們就得借助后端來幫助實現這樣的一個功能需求,具體的實現邏輯是:

用戶————>控制瀏覽器命令行界面————>發送命令到后端服務器————>后端服務器連接socket————>推送用戶的命令

telnet Server ————>后端服務器輸入流接受返回字符——————>websocket 推送到前端完成交互

 

telnet 

可能很多人都知道ssh,估計很少會了解到關於telnet的東西,但是又結合起來說,其實兩個都是一種協議,可以遠程操控,

但是telnet 在傳輸過程中存在着不安全的因素,因為傳輸都未經過加密,而都是明文,這就在遠程連接中,很容易就會被抓包,出現問題,

但SSH 就好比是加強版的telnet ,在傳輸過程中的數據進行加密,進而減少了被盜取的風險。並且所有的SSH都是經過壓縮的,在網絡上的

傳輸速率也很優秀,這樣多方面優秀的情況下,自然而然的就會代替掉telnet 

 

並不是這樣說telnet 就沒什么用了,也不是這樣子的,我們通過搭建這樣一個demo 學習的是這樣的搭建過程中去了解建立連接的過程以及交互的過程

同樣的,就算改編成SSH 其實也是這樣的一個過程,學習就是一個不斷探索的過程

 

 

開始

后端的話,從Springboot 入手,快速的搭建一個web工程,我們主要用這個web工程來接受前端發送過來的命令請求。

包括:連接、斷開、發送命令等等。

最主要的,就是采用commons-net包下面的TelnetClient

        <dependency>
            <groupId>commons-net</groupId>
            <artifactId>commons-net</artifactId>
            <version>3.6</version>
        </dependency>

就好比我們的交換機作為一個Telnet的服務端,而我們的本機就作為一個Telnet的客戶端,客戶端發起請求,服務端相應,與B/S其實一樣的

這里我就摘一些關鍵的部分來進行講解,其他的請clone 項目進行查看

 

創建一個telnet 客戶端

其實創建一個telnet 客戶端是很簡單的,就只需要new一個對象,而后填寫ip地址和端口,端口默認是23,可以不寫,就打開了一個telnet的Connection

        telnetClient = new TelnetClient();
        telnetClient.connect(ip,port);

        inputStream = telnetClient.getInputStream();
        outputStream = telnetClient.getOutputStream();

從客戶端得到兩個流,一個輸入流,一個輸出流,這里就會涉及到JAVA關於IO相關的知識,當然網絡上一般通行都是采用字節流

inputStream 輸入流 outputStread 輸出流

對於輸入流和輸出流相對於模糊的小伙伴,這里給大家加深一下理解,從字面意思上理解

輸入流:就是輸進來的

輸出流:就是丟出去的

其實這樣理解的話,丟失了一個基於的對象。那就是,到底是基於客戶端還是服務端呢,我這里簡單的畫個圖

就好比你的程序要讀取一個文件,這個時候就需要用到輸入流,輸入流提供一個read的方法

我得把日志信息寫入到日志文件里,這個時候就需要用到輸出流,輸出流提供一個write() 方法

輸出流有一個flush() 強制刷新的方法 強制清空和寫入

一個好的習慣,流用完之后要進行關閉!!!!!

 

在當前的環境里面,輸入流就好比是客戶端給我們返回的數據,而輸出流才是我們推送命令的

 

輸入命令

切記在命令后加入一個換行符,這就好比我們在telnet 客戶端上面操作的時候,寫完一句就需要敲一個回車,一樣的道理。

通過輸出流的write 方法寫入到輸出流里面,flush將輸出流清空和強制寫入命令。

    public String sendCommand(String send) throws IOException {

        //加入換行符
         send = send + "\n";

        if (null == telnetClient) {
            return "連接已關閉";
        }
        outputStream.write(send.getBytes());
        outputStream.flush();

        return "發送成功";
    }

 

讀取服務端的返回

上面已經反復敘述過了,服務端的返回我們需要采用輸入流進行接收,同樣的,需要從流里面讀取出我們需要的字節,並將其轉換為字符

通過webSocket 推送到前台進行展示

這時候就需要起一個線程來操作了,因為你不知道什么時候回接收到推送的消息,所以這個線程還不能停掉,得設置為后台線程,讓它在開啟連接后一直

在后台保持活動狀態,這里就需要了解一下:守護線程

 

守護線程 、后台線程

通過給一個線程設置setDaemon(true) 的形式標記這個線程為守護線程,也就是后台線程,線程啟動前必須啟動這個線程

對於停止這個線程的方法嘛 那就是執行中斷,在這個線程的邏輯代碼中判斷是否中斷,中斷則跳出這個線程,線程執行完畢

這個線程也就停掉了唄!

 

 

 通過new 一個線程類,主要看一下這個類的實現方法

outputThread = new InputPrintThread(inputStream);

        //守護線程
        outputThread.setDaemon(true);
        outputThread.start();

通過一個while 循環的方式時刻執行是否中斷的方法和 對輸入流進行讀取,因為讀取在讀取不到字節的時候會發生阻塞,所以這樣是很有必要的

因為在讀取不到的時候,會阻塞這個線程,若讀取流在文件末尾,則會返回-1 我們只需要判斷不是-1繼續讀取就好了

 

注意:這里說的是:讀取出一些字節,並不是所有的字節,一次返回過來的字節它可能會讀取多次,所以不能只循環一次就判斷這個就完了

@Override
    public void run() {

        int num = 0;
        //字節緩沖
        char[] bytes = new char[1024];
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
        try {
            //這里會發生阻塞,通過websocket推送進行
            while (!interrupted() && (num = inputStreamReader.read(bytes)) != -1) {

                for (int i = 0; i < num; i++) {
                    char ab = bytes[i];
                    WebSocketServer.sendInfo(ab + "", SocketIdEnum.TELNET.getValue());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 

webSocket 推送

這一部分對於Springboot 來說整合WebSocket 簡直是太簡單了,一個POM依賴以及簡單的幾行配置即可開啟

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>

這里我就不細說了:我的內容也是參考這一篇文章:請參閱

https://blog.csdn.net/moshowgame/article/details/80275084

 

telnet 客戶端的配置

在windows 里面開啟telnet 基本步驟:搜索windows功能

 

 

找到並開始這一項即可,即可在命令行里面通過telnet + ip 進行遠程訪問,

 

telnet 測試服務端

很多小伙伴在昨晚后,不知如何去測試telnet的連通性以及代碼的測試,缺少一個測試的環境

手頭又沒有其他閑置的電腦或者是交換機,可以參考手頭建立一個虛擬機的方式,這樣也行,或者就

采用華為的ENSP 創建一個虛擬的交換機后,通過自己電腦的虛擬網卡接入到虛擬交換機,這樣其實也是可以通過telnet

進行訪問的,ENSP的安裝這里略過,這里給一個鏈接:https://share.weiyun.com/5kmSEYr

 

而后新建一個交換機通過虛擬網卡的映射進行連接后,通過本機PING 這台交換機的IP 若ping通則證明連接正常

 

 

若不清楚配置交換機的telnet 可以參閱:https://www.cnblogs.com/pipci/p/8075686.html

划分vlan 這些基礎我就不細說了,自行參考

 

測試效果

對與一個寫后台的人來說:前台這樣子其實已經很不錯了 

哈哈 只能簡單的寫個窗口,然后將后台推送的內容push到頁面上 

因為是一個小的測試demo 有興趣的可以進行改造升級更好的CSS美化

小結

關於研究這個web版本的telnet 其實還是涉及到很多東西,比如又再一次的學習到了流的概念以及

之前從未知道這個輸入流還會存在阻塞的問題 以及如何優雅的關閉流以及flush 強制刷新寫入等諸多的問題

雖然SSH已經是遠程當中的主流,telnet 也未必沒得用,總結一下總是好的。

 

參考

交換機telnet配置 https://www.cnblogs.com/pipci/p/8075686.html

springboot 配置websocket https://www.cnblogs.com/pipci/p/8075686.html

 

代碼開源

https://gitee.com/mrc1999/web-telnet


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM