在socket的模块可以发送数据消息的基础上,我们想远程发送一些系统命令来调试服务器。执行系统命令的模块一开始可能给会想到os模块,但我们在使用os模块群无法拿出os模块调用处的结果。如:
import os
res = os.system('dir')
print('命令的结果:', res)
显示结果为:(这里显示乱码,因为Windows系统上文件都为gbk,但pycharm上Global Encoding为utf-8,所以乱码。)
我们在这里看到把res取出来结果为0,这个0是来判断命令是否执行。0代表执行,非0的数字代表执行错误。
os模块无法取出我们想要的东西,我们可以用subprocess模块
1、服务端
import socket
import subprocess # 允许我们启动一个新进程,并连接到它们的输入/输出/管道,从而获取返回值。
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('127.0.0.1', 8841))
server.listen(5)
while True:
conn, client = server.accept()
while True:
try:
# 收命令
cmd = conn.recv(1024)
# 执行命令、拿到结果
obj = subprocess.Popen(cmd.decode('gbk'), shell=True,
stdout=subprocess.PIPE, # 存放命令正确得到结果的通道
stderr=subprocess.PIPE) # 存放命令错误得到结果的通道
stdout = obj.stdout.read() # 把里面的内容读出来放在这里
stdeer = obj.stderr.read()
conn.send(stdout+stdeer) # 可以继续优化
except ConnectionResetError as err:
break
conn.close()
server.close()
2、客户端
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client.connect(('127.0.0.1', 8841))
while True:
cmd = input('>>:').strip()
if not cmd:
continue
client.send(cmd.encode("gbk"))
data = phone.recv(1024) # 发送内容大于1024会出现粘包
print(data.decode("gbk"))
client.close()
Windows操作系统的的命令
dir\ :查看某一个文件夹下的子文件名与子文件夹名
ipconfig: 查看本地网卡的ip地址
tasklist :查看运行的进程