客户端
import socket
import struct
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
phone.connect(('127.0.0.1',9909))
while True:
#1、发命令
cmd=input('>>: ').strip() #ls /etc
if not cmd:continue
phone.send(cmd.encode('utf-8'))
#2、拿命令的结果,并打印
#第一步:先收报头
header=phone.recv(4)
#第二步:从报头中解析出对真实数据的描述信息(数据的长度) 解包
total_size=struct.unpack('i',header)[0]
#第三步:接收真实的数据
recv_size=0
#我接受都是bytes类型
recv_data=b''
#就一直收
while recv_size < total_size:
res=phone.recv(1024) #1024是一个坑
recv_data+=res
#收的长度是res 是真实数据量
recv_size+=len(res)
print(recv_data.decode('utf-8'))
phone.close()
服务端
import socket
import subprocess
import struct
phone=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# phone.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
phone.bind(('127.0.0.1',9909)) #0-65535:0-1024给操作系统使用
phone.listen(5)
print('starting...')
while True: # 链接循环
conn,client_addr=phone.accept()
print(client_addr)
while True: #通信循环
try:
#1、收命令
cmd=conn.recv(8096)
if not cmd:break #适用于linux操作系统
#2、执行命令,拿到结果
obj = subprocess.Popen(cmd.decode('utf-8'), shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout=obj.stdout.read()
stderr=obj.stderr.read()
#3、把命令的结果返回给客户端
#第一步:制作固定长度的报头
total_size = len(stdout) + len(stderr)
#打包
header=struct.pack('i',total_size)
#第二步:把报头发送给客户端
conn.send(header)
#第三步:再发送真实的数据
conn.send(stdout)
conn.send(stderr)
except ConnectionResetError: #适用于windows操作系统
break
conn.close()
phone.close()