嘘~ 正在从服务器偷取页面 . . .

网络通信编程学习(4)—— 基于SOCKET实现模拟SSH远程执行命令


网络通信的应用

根据之前的网络通信的学习,我们可以很简单的想到网络通信可以用于搭建一个类似聊天室的程序。其实网络通信一个重要的应用是连接服务器执行命令,以 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()

运行结果

服务端

客户端


文章作者: New Ass
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 New Ass !
  目录