zoukankan      html  css  js  c++  java
  • Python学习---远程执行命令

    原则:发送一个接受一个

    原理:发送执行命令的大小给客户端,客户端根据接受的大小判断是否全部接收了服务器sendall()发送的全部

    利用send发送的全部数据都是bytes类型的,需要进行字符编码的转换,因为中文环境,所以需要转换GBK查看

    客户端:

    # 客户端
    import socket
    
    # family=AF_INET,   代表使用IPV4的IP协议
    # type=SOCK_STREAM  代表使用TCP协议进行连接
    client = socket.socket()
    ip_addr = ('127.0.0.1', 9999)
    try:
        client.connect(ip_addr)
        exit_flag = True
        while exit_flag:
            # 发送一定要有接收
            inp = input('>>>:')
            if inp != 'bye':
                client.send(bytes(inp, 'utf-8'))
                exit_flag = True
            else:
                client.send(bytes(inp, 'utf-8'))
                exit_flag = False
            result_len = int(str(client.recv(1024), encoding='utf-8')) # 接受服务器端发送的数据大小
            print('客户端接收的大小为:', result_len)
            data_size = bytes()
            while len(data_size) != result_len:
                info = client.recv(1024)    # 最大接收1024K数据,# 传送/接收的数据一定是byte类型
                data_size += info
            print('客户端:', str(data_size, 'gbk')) # Win7系统就是GBK编码返回的数据
    except Exception as e:
        print('客户端关闭连接', e)
    finally:
        client.close()

    服务端:

    # 服务端
    import socket
    import subprocess
    # family=AF_INET,   代表使用IPV4的IP协议
    # type=SOCK_STREAM  代表使用TCP协议进行连接
    server = socket.socket()  # 创建socket
    ip_addr = ('127.0.0.1', 9999)  # 1024之前的端口,默认是OS使用
    server.bind(ip_addr)           # 要求必须是一个元组
    server.listen(3)               # 开始监听传入连接。在拒绝连接之前,可以挂起的最大连接数量。
    while True:
        conn, addr = server.accept() # 接受连接并返回(conn,address)
                                     # 其中conn是新的套接字对象[客户端],可以用来接收和发送数据。
                                     # address是连接客户端的地址。
        exit_flag = True
        while exit_flag:
            print('当前连接对象', addr)
            # 发送一定要有接收
            data = conn.recv(1024)
            print('服务器:', str(data, 'utf-8'))
            obj = subprocess.Popen(str(data, 'utf-8'), shell=True, stdout=subprocess.PIPE)
            cmd_result = obj.stdout.read()  # 编码用GBK,默认在当前文件所在的文件路径
            conn.sendall(bytes(str(len(cmd_result)), encoding='utf-8'))   # 发送数据大小,int不能直接转换为bytes
            print('服务器发送的大小为:', len(cmd_result))  # 某种程度上解决了粘包现象
            conn.sendall(cmd_result)        # 发送全部的数据
    server.close()

    注意:  粘包现象: 在服务器端连续send()的时候,2个send直接会等待很短的时间,所以导致传递过去的len会报错,因为不能转换为int型,可以利用Time.sleep解决,也可以遵循一收一发的原则,发送一个以后在发送一次解决。

  • 相关阅读:
    springboot springcloud zuul 过滤器
    springboot springcloud eureka 熔断器
    javaweb servlet filter
    maven nexus 搭建私服(二)
    springboot springcloud zuul 网关入门
    springboot springcloud 配置中心
    springboot springcloud eureka 入门
    java rabbitmq
    java jvm调优
    maven nexus 搭建私服(一)
  • 原文地址:https://www.cnblogs.com/ftl1012/p/9383739.html
Copyright © 2011-2022 走看看