WebSSH畫龍點睛之lrzsz上傳下載文件

本篇文章沒有太多的源碼,主要講一下實現思路和技術原理

當使用Xshell或者SecureCRT終端工具時,我的所有文件傳輸工作都是通過lrzsz來完成的,主要是因爲其簡單方便,不需要額外打開sftp之類的工具,通過命令就可輕鬆搞定,在用了WebSSH之後一直在想,這麼便捷的操作WebSSH能夠實現嗎?

答案是肯定的,能實現!這要感謝這個古老的文件傳輸協議:zmodem

zmodem採用串流的方式傳輸文件,是xmodem和ymodem協議的改良進化版,具有傳輸速度快,支持斷點續傳、支持完整性校驗等優點,成爲目前最流行的文件傳輸協議之一,也被衆多終端所支持,例如Xshell、SecureCRT、item2等

優點之外,zmodem也有一定的侷限性,其中之一便是隻能可靠地傳輸大小不超過4GB的文件,但對於大部分場景下已夠用,超大文件的傳輸一般也會尋求其他的傳輸方式

lrzsz就是基於zmodem協議實現的文件傳輸,linux下使用非常方便,只需要一個簡單的命令就可以安裝,例如centos系統安裝方式如下

yum install lrzsz

安裝完成後就可以通過rz命令上傳文件,或者sz命令下載文件了,這麼說上傳或下載其實不是很準確,在zmodem協議中,使用receive接收和send發送來解釋更爲準確,無論是receive還是send都是由服務端來發起

rz的意思爲recevie zmodem,服務端來接收數據,對於客戶端來說就是上傳

sz的意思是send zmodem,服務端來發送數據,對於客戶端來說就是下載

文件的傳輸需要服務端和客戶端都支持zmodem協議,服務端通過安裝lrzsz實現了對zmodem協議的支持,Xshell和SecureCRT也支持zmodem協議,所以他們能通過rz或sz命令實現文件的上傳和下載,那麼Web瀏覽器要如何支持zmodem協議呢?

我們所使用的終端工具xterm.js在3.x版本提供過zmodem擴展插件,但很可惜在4.x版本中已經停止支持了,還好給xterm.js提供zmodem擴展插件的作者開源了一個項目:zmodemjs,用來提供瀏覽器Web對zmodem協議的支持,且能很好的跟xterm.js工具相結合,有了zmodemjs我們就可以通過瀏覽器與終端交互,調用系統rzsz命令實現文件上傳下載了

需要注意的是zmodem是個二進制協議,只支持二進制流,所以通過websocket傳輸的數據必須是二進制的,在django的channel中可以通過指定發送消息的類型爲bytes_data來實現websocket傳輸二進制數據,這是後端實現的核心

websocket.send(bytes_data=data)

配合zmodemjs的前端實現,最終的效果如下

當我完成了Web上使用rzsz上傳下載文件功能後,遇到了一個棘手的問題,無論是監控還是錄像,在sz下載時會將下載的文件二進制顯示在屏幕上,這主要是因爲通過zmodemjs可以解析webssh中的二進制文件流爲文件,而監控和錄像不行解析,這就需要監控和錄像時過濾掉文件二進制流,起初我想通過分析二進制流來判斷這段流究竟是文件還是文本,但最後發現無法準確識別,一個稍微靠譜的方法是對binary流進行decode解碼,但不能保證100%準確

又深入研究了zmodem協議是如何實現識別的,發現了zmodem的實現原理

在服務器上執行sz命令後,會先輸出**B00000000000000這樣的內容,標識文件下載開始,當文件下載結束後會輸出OO,取這兩個特殊標記之間的二進制流組合成文件,就是要下載的完整文件

rz命令類似,會在開始時輸出rz waiting to receive.**0100000023be50標記,知道了這個規則,就只需要在發送給監控和錄像的數據中去除sz標記之間的內容就可以了,問題完美解決,算是給WebSSH系列畫上了句號


掃碼關注公衆號查看更多實用文章

相關文章推薦閱讀:

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