server:
'''
远程执行cmd命令程序
如果不使用struct模块,ipconfig等会返回长数据的命令会发生黏包现象
'''
import socket
import struct
sk = socket.socket()
sk.bind(("127.0.0.1", 8080))
sk.listen()
conn, addr = sk.accept()
while True:
cmd = input(">>>")
if cmd == "q":
conn.send(b"q")
break
conn.send(bytes(cmd,encoding="gbk"))
# windows系统的命令行的编码格式是GBK所以要进行GBK转码
num = conn.recv(4)
# 接收返回数据的长度
num = int(struct.unpack("i",num)[0])
# 将接收的bytes类型的struct转换的数字解码,因为返回的是元组所以取元组的第一个,并且下面要用的类型是整数型,转换成int类型
print(conn.recv(num).decode("gbk"))
# 接收上面传进来大小的数据,解码gbk,打印
# 发送多少接收多少就不会产生黏包现象了
conn.close()
sk.close()
client:
import socket
import struct
import subprocess
sk = socket.socket()
sk.connect(("127.0.0.1", 8080))
while True:
cmd = sk.recv(1024).decode("gbk")
# Windows命令行是gbk编码,使用gbk解码
if cmd == "q":
break
res = subprocess.Popen(cmd,shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
# 使用subprocess模块执行cmd命令
# 第一个参数是要执行的命令
# shell=True 表示执行的是系统shell命令
# stdout 执行成功输出信息,保存到管道
# stderr 执行失败输出信息,保存到管道
stdout = res.stdout.read()
# 读取执行成功信息
stderr = res.stderr.read()
# 读取执行失败信息
str_len = len(stdout)+len(stderr)
# 取执行成功和失败信息的长度和
num = struct.pack("i",str_len)
# 使用struct进行数字固定长度编码
# “i” 表示进行转换的是int类型 -> 转换完成后会是固定4字节的bytes类型
# 第二个参数是长度数字
sk.send(num)
# 将长度发送
sk.send(stdout)
# 发送执行成功信息
sk.send(stderr)
# 发送执行失败信息
sk.close()