需求:
编写C/S架构的程序,实现远程执行命令,思路如下
1、客户端接收用户输入的命令,然后发送给服务端,
2、服务端根据传来的数据调用subprocess模块执行系统命令,然后将结果返回给客户端,在客户端打印
错误实例(续更)
错误归纳,续更,(正确示例请挪步下翻至底):
1、在客户端接受到服务端发送的报头,遗漏读取报头长度的错误:
header_bytes = client.recv(header_size)
2、如下图,strcut解包时,得到结果为元组,应当使用索引取值。
header_size = struct.unpack('i',client.recv(4))[0]
正确示例(不断完善中)
client.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/04/20 14:51
# @Author : MJay_Lee
# @File : client.py
# @Contact : limengjiejj@hotmail.com
import socket
import struct
import json
client = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
client.connect(('127.0.0.1',8080))
while True:
cmd = input('请输入通信内容>>:').strip()
client.send(cmd.encode('utf-8'))
header_size = struct.unpack('i',client.recv(4))[0]
header_bytes = client.recv(header_size)
header_json = header_bytes.decode('utf-8')
header_dic = json.loads(header_json)
total_size = header_dic['header_len']
recv_size = 0
res = b''
while recv_size < total_size:
recv_data = client.recv(1024)
res += recv_data
recv_size += len(recv_data)
print(res.decode('gbk'))
# print('来自服务器的消息:',msg.decode('gbk'))
client.close()
server.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/04/20 14:51
# @Author : MJay_Lee
# @File : Sever.py
# @Contact : limengjiejj@hotmail.com
import socket
import subprocess
import json
import struct
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('127.0.0.1',8080))
server.listen(5)
print('start...')
# 循环连接
while True:
conn,client_addr = server.accept()
print(client_addr,'接入服务器')
while True:
try:
msg = conn.recv(1024)
print('来自客户端的消息:', msg.decode('utf-8'))
obj = subprocess.Popen(msg.decode('utf-8'),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
obj_stdout = obj.stdout.read()
obj_stderr = obj.stderr.read()
obj_len = len(obj_stdout) + len(obj_stderr)
header_dic = {
'header_len':obj_len
}
header_json = json.dumps(header_dic)
header_bytes = header_json.encode('utf-8')
# 先发送报头长度
header_size = len(header_bytes)
conn.send(struct.pack('i',header_size))
# 发送报头
conn.send(header_bytes)
conn.send(obj_stdout)
conn.send(obj_stderr)
# conn.send(msg+b'_accept')
except ConnectionResetError:
print(client_addr,'客户端中止链接')
break
conn.close()
server.close()