1. 程式人生 > >Web_telnet 通過JAVA實現網頁上面的命令列遠端工具 以及對於流的理解

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-tel