1. 程式人生 > >Python學習---遠程執行命令

Python學習---遠程執行命令

finally 註意 lose while als bar 元組 類型 time

原則:發送一個接受一個

原理:發送執行命令的大小給客戶端,客戶端根據接受的大小判斷是否全部接收了服務器sendall()發送的全部

利用send發送的全部數據都是bytes類型的,需要進行字符編碼的轉換,因為中文環境,所以需要轉換GBK查看

客戶端:

# 客戶端
import socket

# family=AF_INET,   代表使用IPV4的IP協議
# type=SOCK_STREAM  代表使用TCP協議進行連接
client = socket.socket()
ip_addr = (‘127.0.0.1‘, 9999)
try:
    client.connect(ip_addr)
    exit_flag = True
    while exit_flag:
        # 發送一定要有接收
        inp = input(‘>>>:‘)
        if inp != ‘bye‘:
            client.send(bytes(inp, ‘utf-8‘))
            exit_flag = True
        else:
            client.send(bytes(inp, ‘utf-8‘))
            exit_flag = False
        result_len = int(str(client.recv(1024), encoding=‘utf-8‘)) # 接受服務器端發送的數據大小
        print(‘客戶端接收的大小為:‘, result_len)
        data_size = bytes()
        while len(data_size) != result_len:
            info = client.recv(1024)    # 最大接收1024K數據,# 傳送/接收的數據一定是byte類型
            data_size += info
        print(‘客戶端:‘, str(data_size, ‘gbk‘)) # Win7系統就是GBK編碼返回的數據
except Exception as e:
    print(‘客戶端關閉連接‘, e)
finally:
    client.close()

服務端:

# 服務端
import socket
import subprocess
# family=AF_INET,   代表使用IPV4的IP協議
# type=SOCK_STREAM  代表使用TCP協議進行連接
server = socket.socket()  # 創建socket
ip_addr = (‘127.0.0.1‘, 9999)  # 1024之前的端口,默認是OS使用
server.bind(ip_addr)           # 要求必須是一個元組
server.listen(3)               # 開始監聽傳入連接。在拒絕連接之前,可以掛起的最大連接數量。
while True:
    conn, addr = server.accept() # 接受連接並返回(conn,address)
                                 # 其中conn是新的套接字對象[客戶端],可以用來接收和發送數據。
                                 # address是連接客戶端的地址。
    exit_flag = True
    while exit_flag:
        print(‘當前連接對象‘, addr)
        # 發送一定要有接收
        data = conn.recv(1024)
        print(‘服務器:‘, str(data, ‘utf-8‘))
        obj = subprocess.Popen(str(data, ‘utf-8‘), shell=True, stdout=subprocess.PIPE)
        cmd_result = obj.stdout.read()  # 編碼用GBK,默認在當前文件所在的文件路徑
        conn.sendall(bytes(str(len(cmd_result)), encoding=‘utf-8‘))   # 發送數據大小,int不能直接轉換為bytes
        print(‘服務器發送的大小為:‘, len(cmd_result))  # 某種程度上解決了粘包現象
        conn.sendall(cmd_result)        # 發送全部的數據
server.close()

註意: 粘包現象: 在服務器端連續send()的時候,2個send直接會等待很短的時間,所以導致傳遞過去的len會報錯,因為不能轉換為int型,可以利用Time.sleep解決,也可以遵循一收一發的原則,發送一個以後在發送一次解決。

Python學習---遠程執行命令