利用socket模块编写远程执行命令
1、服务端
# !/usr/bin/env python # -*- coding: utf-8 -*- import socket import subprocess import json import struct sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('127.0.0.1', 8000)) sock.listen(5) while True: try: conn, addr = sock.accept() print(conn, addr) while True: try: # 接受远程客户端命令 cmd = conn.recv(1024) if not cmd: break # 执行客户端发送过来的命令 obj = subprocess.Popen(cmd.decode('utf-8'), stderr=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) err, out = obj.communicate() # 制作固定长度包头 header_dict = { 'total_size': len(err) + len(out), } header = json.dumps(header_dict).encode('utf-8') header_length = struct.pack('i', len(header)) # 先发送包头长度 conn.send(header_length) # 再发送包头 conn.send(header) # 发送真实数据 conn.send(out + err) except ConnectionResetError: break conn.close() except KeyboardInterrupt: break sock.close()
2、客户端
#!/usr/bin/env python # -*- coding: utf-8 -*- import json import struct import socket client = socket.socket() client.connect(('127.0.0.1', 8000)) while True: try: # 输入远程操作命令 cmd = input('>>> ').strip() if not cmd: continue # 发送命令到服务端 client.send(cmd.encode('utf-8')) # 先接受包头长度 header_length = client.recv(4) header_size = struct.unpack('i', header_length)[0] # 再接收包头 header = client.recv(header_size) header_dict = json.loads(header.decode('utf-8')) total_size = header_dict.get('total_size') # 接受真实数据 recv_size = 0 recv_data = b'' while recv_size < total_size: data = client.recv(1024) recv_data += data recv_size += len(data) print(recv_data.decode('utf-8')) except KeyboardInterrupt: break client.close()