使用基于tcp协议的套接字编程实现shell命令符命令执行,获取返回状态/值;
服务端:
from socket import *
import subprocess#subprocess是Python 2.4中新增的一个模块,
# 它允许你生成新的进程,连接到它们的 input/output/error 管道,
# 并获取它们的返回(状态)码
ip_port=("127.0.0.1",8080)
back_log=5
buffer_size=1024*2
tcp_server=socket(AF_INET,SOCK_STREAM)
tcp_server.bind(ip_port)
tcp_server.listen(back_log)
while True:
conn,addr=tcp_server.accept()
while True:
try:
cmd=conn.recv(buffer_size)
if not cmd:break
print("服务器收到的命令:",cmd.decode("utf-8"))
#执行命令,得到命令结果cmd_res
res=subprocess.Popen(cmd.decode("utf-8"),shell=True,
stdout=subprocess.PIPE,
stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
#subprocess.Popen:subprocess模块下的Popen方法,实现:
# 在执行该程序的服务器上实现shell命令的执行;
#subprocess.PIPE--->管道机制:一个程序与另一个程序实现通信,
# 例如:cmd命令提示符与屏幕显示,又如:subprocess 与屏幕显示
#subprocess.POPE,有stdout:标准输出内容扔到管道;
# stdin:标准输入内容扔到管道;
# stderr:标准错误输出内容扔到管道;
#通过read将管道里面的内容一部分一部分的获取读出;
#管道里面的内容,只可读一次,即:丢进管道的内容读一部分少一部分,直到读完;
#stdout\stdin\stderr的内容扔进不同管道,read不冲突;例如:
#如果一个命令执行出错,那么,stderr扔进管道就有内容,stdout就read空;
#所以,这个就可以判断一个命令是否执行有错;
err=res.stderr.read()
# res是一个对象,需要读取res对象的stderr\strout\stdin的属性,才可获取值
#如果:err有值,即表示命令执行报错,即:stdout就为空
if err:
cmd_res=err
else:
cmd_res=res.stdout.read()
conn.send(cmd_res)#注意:cmd_res利用的是系统默认编码:gbk
except Exception:
break
conn.close()
客户端:
from socket import *
tcp_socket_client=socket(AF_INET,SOCK_STREAM)
ip_port=('127.0.0.1',8080)
buffer_size=1024*2
tcp_socket_client.connect(ip_port)
while True:
cmd=input(">>>:请输入命令:").strip()
if not cmd :continue
if cmd=="quit":break
tcp_socket_client.send(cmd.encode("utf-8"))
cmd_res=tcp_socket_client.recv(buffer_size)
if not cmd_res:#cmd_res,执行成功了,但是没有返回值的情况
print("执行成功!",cmd_res.decode("gbk"))
else:
print(cmd_res.decode("gbk"))#系统默认编码:gbk