网络通信的应用
根据之前的网络通信的学习,我们可以很简单的想到网络通信可以用于搭建一个类似聊天室的程序。其实网络通信一个重要的应用是连接服务器执行命令,以 Windows 系统为例,比如说:dir
是查看本地文件目录的命令,ipconfig
是查看本地网卡 IP 地址命令,tasklist
是查看运行进程的命令……
python 如何利用代码执行终端命令
而要实现远程执行命令我们要做的是将相应命令传输给服务端,并让服务端将执行命令的结果返回客户端。
所以我们首先要解决的问题是如何利用代码执行终端命令。
尝试一、os
模块
不出意外,我们首先想要的实现方法是 os
模块。运行代码及结果如下
# coding=gbk
import os
os.system("ipconfig")
看运行结果,好像我们已经解决问题了,但仔细想想我们这段代码是写在 服务端的,我们需要做的是获取执行后得到的结果传递给客户端,但现在却是直接在服务端打印结果了。
那么面对这个问题我们可以通过赋值解决吗?
答案是否定的。
# coding=gbk
import os
res = os.system("ipconfig")
print(res)
我们发现自己的赋值结果得到的是 0.其实这个零表示的是我们提供的命令可以执行并且执行成功。这也意味着利用 os
模块并不能得到我们想要的结果。
解决方法、subprocess
模块
代码及实现
# coding=gbk
import subprocess
cmd = input(">>: ").strip()
# shell 一定不要忘记,不然该命令不会执行
# stdout 表示可以执行并且执行成功后的结果,PIPE 表示结果送至管道
# stderr 表示无法执行的结果
obj = subprocess.Popen(cmd, shell=True,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
stdout = obj.stdout.read() # 结果获取
stderr = obj.stderr.read()
print(stdout.decode("gbk")) # windows 系统上终端以 gbk 编码方式输出,所以打印的时候要转换成 gbk 编码
print(stderr.decode("gbk"))
成功的结果
失败的结果
代码实现
将 subprocess
相关的代码加入服务端
服务端代码
# coding=gbk
import socket
import subprocess
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
phone.bind(("127.0.0.1", 8080))
phone.listen(5)
while True: # 连接循环
conn, addr = phone.accept()
print("starting……")
print(addr)
while True: # 通信循环
try:
cmd = conn.recv(1024)
if not cmd:
break
print(addr,"发出的命令是:", cmd)
obj = subprocess.Popen(cmd.decode("gbk"), shell=True,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE)
stdout = obj.stdout.read()
stderr = obj.stderr.read()
res = stdout + stderr
conn.send(res)
except ConnectionResetError:
break
conn.close()
phone.close()
客户端代码
# coding=gbk
import socket
phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
phone.connect(("127.0.0.1", 8080))
while True: # 通信循环
cmd = input(">>--: ").strip()
if not cmd:
continue
phone.send(cmd.encode("gbk"))
res = phone.recv(1024)
print(res.decode("gbk"))
phone.close()
运行结果
服务端
客户端