模擬遠端SSH執行命令的編譯碼說明

2022-04-29 02:33:06 字數 3127 閱讀 6272

模擬乙個ssh「遠端」執行命令並獲取命令結果的乙個程式:

1、在c/s架構下,當客戶端與伺服器建立連線(這裡以tcp為例)後,二者可以不斷的進行資料互動。ssh遠端可以實現的效果是客戶端輸入命令可以在伺服器中執行並且可以將結果返回給客戶端。但是需要注意的一點事:客戶端的「命令」在計算機看來僅僅是「字串」而已,而真正需要執行的「命令」必須是作業系統能夠識別的!也就是說,真正「執行命令」與「返回結果」的地方仍然是伺服器端。在客戶端我們只是「顯示」出了乙個這樣的知執行假象而已。

那麼,這樣的乙個ssh遠端執行程式的具體流程是怎樣的呢?

下圖是這樣的乙個簡單過程:

簡單的過程說明:

對於客戶端來講,使用者首先輸入了str型別的命令command,然後程式將這個str型別的字串encode成能夠在網路中傳輸的bytes型別的資料並傳送給伺服器;伺服器接收到以後將其重新解碼為str,然後在本段「執行」這段**生成str型別的結果,接著再進行編碼傳給客戶端,客戶端接收到以後解碼為人能識別的str型別最終輸出到螢幕上。

2、這個過程有兩個大問題:乙個是伺服器端是如何進行「**執行」的,另乙個就是客戶端與伺服器端str與bytes格式資料的編譯碼問題。

2.1、對於第乙個問題,我們利用subprocess模組下的popen方法可以將str型別的「虛假命令」轉換為作業系統能夠識別的「真是命令」:

import

subprocess

cmd = input('

>>>:')

obj = subprocess.popen(cmd,shell=true,stdout=subprocess.pipe,stderr=subprocess.pipe)

print(obj.stdout.read().decode('

gbk'

))print(obj.stderr.read().decode('

gbk'))

這裡有幾點需要說明:

(1)可以把obj看成是乙個管道,它一次性的、毫無保留將所有執行結果都拿到,再一次取值時裡面沒有了資料,這就像乙個「管道」一樣,裡面的資料全部取完後就「無所保留」了。

(2)關於輸出結果解碼的問題:subprocess模組下的popen方法在不同的作業系統下結果的編碼方式不同:linux下為utf-8模式,windows下為gbk模式。由於本例是在windows作業系統下進行的,所以我們在輸出是要進行gbk的方式解碼才能看到結果。

(3)最終的結果包含正確的資訊stdout與錯誤的結果stderr(當使用者輸入乙個不存在的命令時產生)。

2.2、第二個編譯碼問題可以看下圖具體的描述:

這裡需要注意的一點是:本例是在windows作業系統下執行的,所以result的編碼方式要以gbk模式進行,這樣才不會在客戶端中產生亂碼。

程式的**以及執行結果為:

import

socket

import

subprocess

server_whw =socket.socket(socket.af_inet,socket.sock_stream)

server_whw.setsockopt(socket.sol_socket,socket.so_reuseaddr,1)

server_whw.bind((

'127.0.0.1

',8008))

server_whw.listen(5)

print('

starting......')

conn,client_addr =server_whw.accept()

while 1:

try:

cmd = conn.recv(8096)

#將從客戶端傳來的命令資訊進行處理

obj = subprocess.popen(cmd.decode('

utf-8

'),shell=true,stdout=subprocess.pipe,stderr=subprocess.pipe)

#將結果返回給客戶端

stdout = obj.stdout.read().decode('

gbk'

) stderr = obj.stderr.read().decode('

gbk'

) std1 = stdout.encode('

gbk'

) std2 = stderr.encode('

gbk'

) conn.send(std1)

conn.send(std2)

except

connectionreseterror:

print('

連線斷開')

break

conn.close()

server_whw.close()

server_ssh

import

socket

client_whw =socket.socket(socket.af_inet,socket.sock_stream)

client_whw.connect((

'127.0.0.1

',8008))

while 1:

cmd = input('

請輸入命令:')

ifnot

cmd:

continue

client_whw.send(cmd.encode(

'utf-8'))

data = client_whw.recv(1024)

print('

命令結果:\n

',data.decode('

gbk'))#

client_whw.close()

client_ssh

程式演示:

當然,最終的結果出現了粘包問題~需要進行進一步的處理

模擬ssh遠端執行命令

目錄python從入門到放棄完整教程目錄 from socket import import subprocess server socket af inet,sock stream server.bind 127.0.0.1 8000 server.listen 5 print start.whi...

模擬ssh遠端執行命令

from socket import import subprocess server socket af inet,sock stream server.bind 127.0.0.1 8000 server.listen 5 print start.while true conn,client a...

鏈結迴圈 模擬遠端執行命令 實現大檔案上傳

迴圈鏈結 服務端 import socket server socket.socket server.bind 127.0.0.1 8080 server.listen 5 要實現迴圈鏈結,也就是乙個鏈結段了之後,我們又可以繼續鏈結其他的 服務端要提供持續不斷的服務 while true conn,...