编写远程执行命令的CS架构软件

1. TCP服务端

import socket
import subprocess

server = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
server.bind(("127.0.0.1", 8080))
server.listen(5)
while True:  # 连接循环
    conn, client_addr = server.accept()
    print("有客户端建立连接........")
    while True:  # 通讯循环
        try:
            data_bytes = conn.recv(1024)
            if not data_bytes:
                # 这里解决的问题是:
                # 当你的程序运用在linux系统中,客户端强制断开链接,服务端会收到空的数据,在这种情况下就会退出与当前客户端的通讯循环,并关闭与该客户端的连接, 并回收当前客户端在服务端当前所占的系统资源,
                # 还有另一种情况就是客户端正常使用close()断开连接, 服务端也会收到空的数据,
                break
            obj = subprocess.Popen(
                data_bytes.decode('utf-8'),
                shell=True,
                stderr=subprocess.PIPE,
                stdout=subprocess.PIPE,
            )
            # 注意!!!: subprocess如果执行的是'tasklist'命令, read获取正确结果要在错误结果之前(补充: 具体为什么目前我也不知道,不过执行其他的命令没有这种要求,)
            stdout, stderr = obj.stdout.read(), obj.stderr.read()
            # print('stderr:', stderr)
            # print('stdout:', stdout)
            conn.sendall(stdout)
            conn.sendall(stderr)
        except ConnectionResetError:
            # 解决的问题是:
            # 当你的程序运行在windows系统中,客户端强制断开链接,服务端就会引发异常. 因此,就可以使用异常处理机制来监测这种异常,此时一旦监测出这种异常,就代表客户端强制断开了链接.
            # 在这种情况下就会退出与当前客户端的通讯循环,并关闭与该客户端的连接, 并回收当前客户端在服务端当前所占的系统资源,
            break
    conn.close()
server.close()

2. TCP客户端

import socket

client = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
client.connect(('127.0.0.1', 8080))
while True:
    cmd = input("输入命令: ").strip()

    if not cmd:
        # 这里解决的问题,当客户端输入为空的时候,在客户端的操作系统缓存中,并没有数据能发送给服务端. 硬件不能识别你这个空的数据,只有我们这种逻辑层面才有这种空的数据的存在.
        # 因此服务端的recv操作会在服务端的操作缓存中拿取数据,但是与此同时,服务端的操作系统缓存中并没有数据,于是服务端一直在recv堵塞状态.
        # 接着客户端因为send发送了数据,处于recv等待服务端发送回来的数据的状态,因而两者会处于一种recv堵塞的状态,
        continue
    client.send(cmd.encode('utf-8'))
    data_bytes = client.recv(8096)
    print(data_bytes.decode('gbk'))
client.close()
posted @ 2020-04-20 21:00  给你加马桶唱疏通  阅读(285)  评论(0编辑  收藏  举报