Python 基于TCP实现远程执行命令

Python 基于TCP实现远程执行命令

服务端

from  socket import *
import subprocess
import struct

# address=('127.0.0.1',8000)
# back_log=5
# buffer_size=1024

tcp_server=socket(AF_INET,SOCK_STREAM)  ##定义tcp协议的socket接口
tcp_server.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) ##加入这条socket配置,重用IP和端口,还可以在操作系统上配置ip和端口重用
tcp_server.bind(('127.0.0.1',8000))   ##为套接字绑定IP和端口,(IP和端口可以标示全网唯一)
tcp_server.listen(5)  ## 可以接收的接收的连接数,并且监听端口

while True:
    conn,addr=tcp_server.accept()  ##建立链接,并堵塞端口
    print(addr)
    while True:
        try:  ## 异常处理,防止客户端不正常断开
            data_cmd = conn.recv(1024)   ## 接收消息
            if not data_cmd:break   ##防止接收的消息为空
            print('收到客户端的命令')
            ## 通过subprocess.Popen执行操作系统命令,并且把返回值重定向到subprocess.PIPE的管道零时存放
            res = subprocess.Popen(data_cmd.decode('utf-8'), shell=True,stderr=subprocess.PIPE,\
                                   stdout=subprocess.PIPE,stdin=subprocess.PIPE)
            err = res.stderr.read()  ##通过res.stderr.read()读取错误消息
            if err:
                res_data=err
            else:
                res_data=res.stdout.read()  ##通过res.stdout.read()读取标准输出消息
            if not res_data:
                res_data = '执行成功'.encode('gbk')  ##防止操作系统执行命令后,返回值为空时,为客户端返回此消息
            length = len(res_data)  ## 计算返回值数据长度
            data_length = struct.pack('i', length)  ## 通过struct.pack处理返回值数据长度,并且也只能占用4个字节
            conn.send(data_length)   ## 发送返回值数据长度(4字节)作为返回给客户端消息的包头,因为是定长的,所\
            # 以客户端在接收时,第一次接收4个字节,就知道服务端返回的消息长度,就可以到自己的内存按次长度获取数据
            conn.send(res_data)  ## 发送数据
        except Exception as e:
            print(e)  ##处理方式
            break

客户端

from socket import *
import subprocess
import struct
# ip_port=('127.0.0.1',8000)
buff_size=1024

tcp_client=socket(AF_INET,SOCK_STREAM)
tcp_client.connect(('127.0.0.1',8000))   ## 链接服务端

while True:
    cmd_data=input('请输入命令:')    ## 输入命令
    if not cmd_data:continue       ##判断是否输入空值,为空跳出本次循环,让用户重新输入
    if cmd_data == 'quit': break    ## 当用户输入quit时,断开链接(相当于不正常断开)
    tcp_client.send(cmd_data.encode('utf-8'))  ## 发送命令

    length_data = tcp_client.recv(4)    ## 第一次接收4字节,就是服务端用struct.pack封装为4字节的包头
    head_data=struct.unpack('i',length_data)[0]  ## 街封装,结果是列表类型

    # 处理数据
    res_length=0
    res_msg=b''
    while res_length < head_data:
        res_msg += tcp_client.recv(buff_size)
        res_length += len(res_msg)
        print(res_length)
    print('命令的执行结果是 ', res_msg.decode('gbk'))
tcp_client.close()

输出结果:

## 服务端:
('127.0.0.1', 63745)
收到客户端的命令 dir
## 客户端:
请输入命令:dir
903
命令的执行结果是   驱动器 D 中的卷是 软件
 卷的序列号是 65F3-3762

 D:\python\study\socket01 的目录

2020/03/10  18:57    <DIR>          .
2020/03/10  18:57    <DIR>          ..
2020/03/08  19:55               231 client.py
2020/03/10  18:57             1,067 cmd_client_tcp.py
2020/03/10  18:57             2,290 cmd_server_tcp.py
2020/03/09  15:54               333 ntp-client.py
2020/03/09  16:25               468 ntp-server.py
2020/03/08  19:54               315 server.py
2020/03/09  15:54               333 udp-client.py
2020/03/09  15:54               320 udp-server.py
2020/03/08  19:34                 0 __init__.py
2020/03/08  22:34               443 客户端.py
2020/03/08  22:33               445 客户端11.py
2020/03/08  22:33               720 服务端.py
2020/03/10  17:12    <DIR>          练习
              12 个文件          6,965 字节
               3 个目录 76,889,382,912 可用字节
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值