• 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解决,也可以遵循一收一发的原则,发送一个以后在发送一次解决。

  • 相关阅读:
    .net类库里ListView的一个BUG
    获取lable的caption, 摘抄还未测试可用否
    (转) lua实现split的简易方法
    2. SharePoint Online 开发,请联系qq512800530。加好备注。(不要发站内信。。。)
    1. android
    开发人员应关注的20个jQuery网站/博客
    Temp
    彩票项目开发节项
    求android ble 解决方案!
    自己开发的工作流引擎
  • 原文地址:https://www.cnblogs.com/ftl1012/p/9383739.html
Copyright © 2020-2023  润新知